2

我有两张桌子。

表格1

ID  Code1 Code2 Code3
10    1.1   1.2   1.3

表 2

Code  Group  Category
1.1     a     cat1
1.2     b     cat1
1.3     c     cat2
1.4     d     cat3

现在我需要从这两个表中获取两种不同形式的输出

输出 1

ID   Group1  Group2  Group3
10     a       b       c

输出 2

ID   cat1   cat2   cat3
10     1     1      0   

这里的 cat1、cat2、cat3 列本质上是布尔值,因为表 1 没有任何与 cat3 对应的代码,因此其值为 0。

我正在考虑用案例陈述来做这件事,但大约有 1000 个代码映射到大约 50 个类别。他们有办法做到这一点吗?我正在努力为此提出一个查询。

4

5 回答 5

0

这些答案假定表 2 中的所有 3 个代码都可用。如果没有,那么您应该使用 OUTER 连接而不是 INNER。

输出 1 可以这样实现:

select t1.ID,
       cd1.Group as Group1,
       cd2.Group as Group2,
       cd3.Group as Group3
from table1 t1
inner join table2 cd1
on t1.Code1 = cd1.Code
inner join table2 cd2
on t1.Code2 = cd2.Code
inner join table2 cd3
on t1.Code3 = cd3.Code

输出 2 更棘手。由于您希望 Table2 中的每一行都有一个列,因此您可以编写编写 SQL 的 SQL。

基本上从这个基本语句开始:

select t1.ID,
//THE BELOW WILL BE GENERATED ONCE PER ROW
Case when cd1.Category = '' OR 
          cd2.Category = '' OR
          cd3.Category = '' then convert(bit,1) else 0 end as '',
//END GENERATED CODE
from table1 t1
inner join table2 cd1
on t1.Code1 = cd1.Code
inner join table2 cd2
on t1.Code2 = cd2.Code
inner join table2 cd3
on t1.Code3 = cd3.Code

然后你可以像这样在中间生成代码:

select distinct 'Case when cd1.Category = '''+t2.Category+''' OR 
          cd2.Category = '''+t2.Category+''' OR
          cd3.Category = '''+t2.Category+''' then convert(bit,1) else 0 end as ['+t2.Category+'],'
from table2 t2

将这些结果粘贴到原始 SQL 语句中(去掉结尾的逗号),你应该可以开始了。

于 2013-06-27T20:40:53.547 回答
0

首先,我强烈建议您寻找替代方案。这将很快变得混乱,因为您实际上将行视为列。已经非规范化并没有太大帮助Table1- 尽管如果它真的只有 3 列,那么再次规范化它并不是什么大不了的事。:

CREATE VIEW v_Table1 AS
   SELECT Id, Code1 as Code FROM Table1
   UNION SELECT Id, Code2 as Code FROM Table1
   UNION SELECT Id, Code3 as Code FROM Table1

如果我们带您进行第二个查询,您似乎需要 and 的所有可能组合,ID以及Category该组合是否出现在中的布尔值Table2Code用于返回IDin Table1)。

由于似乎没有 and 的规范列表IDCategory我们将生成它:

CREATE VIEW v_AllCategories AS
   SELECT DISTINCT ID, Category FROM v_Table1 CROSS JOIN Table2

获取代表列表ID并且Category非常简单:

CREATE VIEW v_ReportedCategories AS
   SELECT DISTINCT ID, Category FROM Table2 
   JOIN v_Table1 ON Table2.Code = v_Table1.Code

把它们放在一起,我们就可以得到布尔值来告诉我们哪个存在:

CREATE VIEW v_CategoryReports AS
    SELECT
       T1.ID, T1.Category, CASE WHEN T2.ID IS NULL THEN 0 ELSE 1 END as Reported
    FROM v_AllCategories as T1
    LEFT OUTER JOIN v_ReportedCategories as T2 ON
       T1.ID = T2.ID
       AND T1.Category = T2.Category

这会让你以标准化的形式得到你的答案:

ID  | Category | Reported
10  | cat1     | 1
10  | cat2     | 1
10  | cat3     | 0    

从那里,您需要执行 aPIVOT以将您的Category值作为列:

SELECT
    ID,
    cat1,
    cat2,
    cat3
FROM v_CategoryReports
PIVOT (
    MAX([Reported]) FOR Category IN ([cat1], [cat2], [cat3])
) p

由于您提到了 50 多个“类别”,我假设它们不是真正的“cat1”-“cat50”。在这种情况下,您需要编写生成枢轴操作的代码。

带有自包含示例的 SqlFiddle。

于 2013-06-27T21:26:53.783 回答
0

我们可以使用 Pivot 功能并动态构建查询。一些如下所示:

查询 1

Select * from 
(SELECT Id, Code, GroupCode
FROM Table2 join Table1 
 ON Table1.Code1 = Table2.Code 
 OR Table1.Code2 = Table2.Code 
 OR Table1.Code3 = Table2.Code 
) ps
PIVOT
(
Max (GroupCode)
FOR Code IN
( [1.1], [1.2], [1.3])
) AS Result

查询 2

Select * from 
(SELECT Id, GroupCode, Category
FROM Table2 join Table1 
 ON Table1.Code1 = Table2.Code 
 OR Table1.Code2 = Table2.Code 
 OR Table1.Code3 = Table2.Code 
) ps
PIVOT
(
Count (GroupCode)
FOR Category IN
( [cat1], [cat2], [cat3])
) AS Result
于 2013-06-27T21:29:21.300 回答
-1

MSSQL 中的 PIVOT 和 CROSS APPLY 关键字可以帮助您。尽管尚不清楚您要完成什么。CROSS APPLY 用于对相关子查询执行连接并为每个连接显示不同的输出,PIVOT 用于对数据进行交叉表。

对于表 1,如果将其混合成更规范的样式可能会更容易。

WITH cteTab1 (Id, Code) AS
(
SELECT Id, Code1 FROM Table1
UNION ALL
SELECT Id, Code2 FROM Table1
UNION ALL
SELECT Id, Code3 FROM Table1)
SELECT *
FROM Table2 INNER JOIN cteTab1 ON Table2.Code = cteTab1.Code
于 2013-06-27T20:39:37.013 回答
-1

不幸的是,您对 Table1 的设计很糟糕。更好的方法是为 ID 10 设置 3 行。

但是,鉴于您当前的设计,您的查询将如下所示:

SELECT ID, G1.Group Group1, G2.Group Group2, G3.Group Group3
FROM Table1 T1
INNER JOIN Table2 G1 ON T1.Code1 = G1.Code
INNER JOIN Table2 G2 ON T1.Code2 = G2.Code
INNER JOIN Table2 G3 ON T1.Code3 = G3.Code

SELECT ID, G1.Category Cat1, G2.Category Cat2, G3.Category Cat3
FROM Table1 T1
INNER JOIN Table2 G1 ON T1.Code1 = G1.Code
INNER JOIN Table2 G2 ON T1.Code2 = G2.Code
INNER JOIN Table2 G3 ON T1.Code3 = G3.Code
于 2013-06-27T20:43:44.117 回答