繁体   English   中英

返回 SQL 中行上所有可能的值组合

[英]Return all possible combination of values on Rows in SQL

如何返回行中所有值组合的列表? 预期的输入和结果将在 T-SQL 中如下所示,

   Id          Category        Value
  ----        --------      --------
Source1        Company        GreenChef
source1        Company        Chef-client
source1        Role           Master
source1        Level          key1
source1        Level          key2
source1        Level          key3

预期的结果将是这样的。

Id        Company     Level       Role 
--        -------     -----      ------
source1   GreenChef   Key1       Master 
source1   GreenChef   Key2       Master
source1   GreenChef   Key3       Master
Source1   Chef-client Key1       Master
Source1   Chef-client Key2       Master
Source1   Chef-client Key3       Master

如果您知道category中的值,那么这是笛卡尔积。 但是,您可能想要每个 id

select i.id, c.company, r.role, l.level
from (select distinct id
      from t
     ) i left join
     (select distinct id, value as company
      from t
      where category = 'Company'
     ) c
     on c.id = i.id left join
     (select distinct id, value as role
      from t
      where category = 'Role'
     ) r 
     on r.id = i.id left join
     (select distinct id, value as level
      from t
      where category = 'Level'
     ) l
     on l.id = i.id;

这从一个完整的 id 列表开始,这可能只是一种方便。 它使用left join ,因此它将返回所有 id,即使是那些缺少角色之一的。

如果您不知道所有类别,仍然可以使用递归 CTE 解决问题。 为此,我建议提出一个问题。

如果类别列表是固定的,那么

select t.id, t1.value as Company, t2.value as Level, t3.value as Role
from (select distinct id 
      from mytable 
) t
cross apply (
   select distinct Value 
   from mytable t1
   where Category ='Company'
   and t1.id = t.id) t1
cross apply (
   select distinct Value 
   from mytable t2
   where Category ='Level'
   and t2.id = t.id) t2
cross apply (
   select distinct Value 
   from mytable t3
   where Category ='Role'
   and t3.id = t.id) t3

否则,您可以使用动态 sql。

您需要自行加入表格:

with companies as (select * from mytable where category = 'Company')
   , roles     as (select * from mytable where category = 'Role')
   , levels    as (select * from mytable where category = 'Level')
select c.id, c.value as company, r.value as role, l.value as level
from companies c
join roles r on r.id = c.id
join levels l on l.id = c.id;

这里使用USING而不是ON会更优雅,但是 SQL Server 不支持。 这与内部联接无关紧要,但如果可能缺少任何属性,则需要完整的外部联接。 如果没有USING的同一列上有两个以上的表(在您的情况下是派生表),这会变得非常笨拙。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM