在TSQL中学习数据透视

时间:2018-12-31 13:59:28

标签: tsql pivot

我觉得这应该很简单,但是我发现的所有枢纽似乎都比我要寻找的要复杂,因此我们将不胜感激任何帮助或重定向。

我有“ ID_code”和“ product_name”,我正在寻找不匹配的产品名称,并将它们排成一行,而不是像这样的列:

Select distinct ID_Code, product_name
From table
Where ID_Code in
(Select ID_Code from table
Group by ID_Code
Having count(distinct product_name) <> 1)

我想要一张摆成的桌子

ID码产品名1产品名2产品名3

非常感谢,新年快乐!

2 个答案:

答案 0 :(得分:1)

这应该删除重复项,但是如果product_name匹配则仍然返回一个结果。

;with testdata as(
SELECT '1' as ID_Code, 'bike' as product_name
UNION ALL SELECT '1', 'biker'
UNION ALL SELECT '1', 'bike'
UNION ALL SELECT '2', 'motorbike'
UNION ALL SELECT '2', 'motorbike'
UNION ALL SELECT '2', 'motorbike'
UNION ALL SELECT '2', 'motrbike'
UNION ALL SELECT '2', 'motorbiker'
)

--added this section to return distinct products
,cte as(
SELECT * FROM testdata d1
INTERSECT
SELECT * FROM testdata d2
)

SELECT --DISTINCT   --Use DISTINCT here if need to return just one line per ID_Code 

    ID_Code
    ,product_name = STUFF((SELECT ', ' +
                        --Added this to track product_names for each ID_Code
                        t2.product_name + '_' + cast(ROW_NUMBER() OVER (PARTITION BY ID_Code ORDER BY product_name) as varchar(100))
      FROM cte t2
      WHERE t2.ID_Code = cte.ID_Code
      FOR XML PATH('')), 1, 2, '')

FROM cte

此处的示例:db<>fiddle

有关INTERSECT的更多信息,在这种情况下不可行。

答案 1 :(得分:0)

您的预期输出似乎有些不灵活,因为我们可能不知道确切需要多少列/产品。相反,我建议并将不匹配的产品汇总到CSV字符串中以进行输出。

SELECT
    ID_Code,
    STUFF((SELECT ',' + t2.product_name
      FROM yourTable t2
      WHERE t1.ID_Code = t2.ID_Code
      FOR XML PATH('')), 1, 1, '') products
FROM your_table t1
GROUP BY
    ID_Code
HAVING
    MIN(product_name) <> MAX(product_name);    -- index friendly

enter image description here

Demo