我可以从 select 案例陈述中得到一对多吗?

Can i have a one to many from a select case statement?

我有两个 table 正在为工作中的项目工作。第一个 table (crm_users) 有 id、用户名和 16 个以“state_license_”开头的字段,结尾是州缩写。

第二个 table 对用户名字段有唯一约束,因此 1 个用户名最多可以有 16 条记录,这就是我希望 table 的样子。

以下查询 returns 仅在第一个状态许可和停止,但我想在第二个 table (users_licenses) 中填充所有记录,再次使用最多 16 条记录只需一个用户名。

例如,Greg 是 crm_users table 的用户,并且在所有 16 个州都获得了许可。我想让 users_licenses Greg 拥有他的用户名和 16 条记录,显示每个州的名称。

-- insert into users_licenses(crm_userid, username, licensed_in)
select distinct id, username, 
(case when state_license_AL = 'Yes' then 'Alabama' end) as licensed_in,
(case when state_license_CA = 'Yes' then 'California' end) as licensed_in,
(case when state_license_CO = 'Yes' then 'Colorado' end) as licensed_in,
(case when state_license_CT = 'Yes' then 'Connecticut' end) as licensed_in,
(case when state_license_FL = 'Yes' then 'Florida' end) as licensed_in,
(case when state_license_GA = 'Yes' then 'Georgia' end) as licensed_in,
(case when state_license_MD = 'Yes' then 'Maryland' end) as licensed_in,
(case when state_license_MI = 'Yes' then 'Michigan' end) as licensed_in,
(case when state_license_MN = 'Yes' then 'Minnesota' end) as licensed_in,
(case when state_license_NJ = 'Yes' then 'New Jersey' end) as licensed_in,
(case when state_license_OH = 'Yes' then 'Ohio' end) as licensed_in,
(case when state_license_OR = 'Yes' then 'Oregon' end) as licensed_in,
(case when state_license_PA = 'Yes' then 'Pennsylvania' end) as licensed_in,
(case when state_license_TN = 'Yes' then 'Tennessee' end) as licensed_in,
(case when state_license_VA = 'Yes' then 'Virginia' end) as licensed_in,
(case when state_license_WA = 'Yes' then 'Washington' end) as licensed_in
from crm_users
group by id, username

我们将不胜感激任何建议。谢谢。

我很难在不抛出错误的情况下完全运行查询。无论如何,您的模式很糟糕,它会让您陷入令人沮丧的逻辑。您可能无法控制模式,但如果您控制了,则将此 table 更改为 id, username, region, is_licensed。当前的架构感觉像是一种“Excel”的数据思考方式。

如果您无法控制模式,那么 UNION 查询是可行的方法:

SELECT id, username, 'Alabama' as region, state_license_AL AS is_licensed FROM crm_users
UNION ALL
SELECT id, username, 'California', state_license_CA FROM crm_users
UNION ALL
SELECT id, username, 'Colorado', state_licens_CO FROM crm_users
UNION ALL
SELECT id, username, 'Connecticut'... /*so on and so forth*/

虽然这不能得到您的确切输出,但它确实可以使您的数据处于更好的查询状态。您可以将那个东西包装在 SELECT 和过滤器中:

SELECT *
FROM
    (
      SELECT id, username, 'Alabama' as region, state_license_AL as is_licensed FROM crm_users
      UNION ALL
      SELECT id, username, 'California', state_license_CA FROM crm_users
      UNION ALL
      SELECT id, username, 'Colorado', state_licens_CO FROM crm_users
      UNION ALL
      SELECT id, username, 'Connecticut'... /*so on and so forth*/
    )subquery
WHERE subquery.is_licensed = 'Yes'

显然,如果您愿意,您可以在不使用子查询的情况下直接进入 UNION 查询:

SELECT id, username, 'Alabama' as region, state_license_AL FROM crm_users WHERE state_license_AL = 'Yes'
UNION ALL
SELECT id, username, 'California', state_license_CA FROM crm_users WHERE state_license_CA = 'Yes'
UNION ALL
SELECT id, username, 'Colorado', state_licens_CO FROM crm_users WHERE state_license_CO = 'Yes'
UNION ALL
SELECT id, username, 'Connecticut'... /*so on and so forth*/

但这感觉很笨拙,根据第一个建议,您可以 re-use 在处理这些数据时一遍又一遍地编写该代码。

您需要 UNPIVOT 函数,但 MySQL 没有。如果没有,最好的选择是 UNION ALL.

select id,  username, 'Alabama' as State, state_license_AL from crm_users union all
select id,  username, 'California' as State, state_license_CA from crm_users union all
select id,  username, 'Colorado' as State, state_license_CO from crm_users union all
select id,  username, 'Connecticut' as State, state_license_CT from crm_users union all
select id,  username, 'Florida' as State, state_license_FL from crm_users union all
select id,  username, 'Georgia' as State, state_license_GA from crm_users union all
select id,  username, 'Maryland' as State, state_license_MD from crm_users union all
select id,  username, 'Michigan' as State, state_license_MI from crm_users union all
select id,  username, 'Minnesota' as State, state_license_MN from crm_users union all
select id,  username, 'New Jersey' as State, state_license_NJ from crm_users union all
select id,  username, 'Ohio' as State, state_license_OH from crm_users union all
select id,  username, 'Oregon' as State, state_license_OR from crm_users union all
select id,  username, 'Pennsylvania' as State, state_license_PA from crm_users union all
select id,  username, 'Tennessee' as State, state_license_TN from crm_users union all
select id,  username, 'Virginia' as State, state_license_VA from crm_users union all
select id,  username, 'Washington' as State, state_license_WA from crm_users ;
id | username | State        | state_license_AL
-: | :------- | :----------- | :---------------
 1 | Greg     | Alabama      | Yes             
 1 | Greg     | California   | Yes             
 1 | Greg     | Colorado     | Yes             
 1 | Greg     | Connecticut  | Yes             
 1 | Greg     | Florida      | Yes             
 1 | Greg     | Georgia      | Yes             
 1 | Greg     | Maryland     | Yes             
 1 | Greg     | Michigan     | Yes             
 1 | Greg     | Minnesota    | Yes             
 1 | Greg     | New Jersey   | Yes             
 1 | Greg     | Ohio         | Yes             
 1 | Greg     | Oregon       | Yes             
 1 | Greg     | Pennsylvania | Yes             
 1 | Greg     | Tennessee    | Yes             
 1 | Greg     | Virginia     | Yes             
 1 | Greg     | Washington   | Yes             

db<>fiddle here