2行到1行 - 嵌套查询

时间:2014-12-17 14:35:23

标签: sql sql-server-2008 sql-server-2012

我有一个响应列,根据问题1和问题2为同一产品存储2个不同的值。这为每个产品创建了2行,但我希望每个产品只有一行。 例如:

select Product, XNumber from MyTable where QuestionID IN ('Q1','Q2')

结果显示:

Product  XNumber
Bat      abc
Bat      abc12

我希望它显示如下:

Product    Xnumber1  Xnumber2
Bat        abc       abc12

请帮忙。 感谢。

5 个答案:

答案 0 :(得分:1)

如果您总是有两个不同的值,可以试试这个:

SELECT a.Product, a.XNumber as XNumber1, b.XNumber as XNumber2
FROM MyTable a
INNER JOIN MyTable b
ON a.Product = b.Product
WHERE a.QuestionId = 'Q1'
AND b.QuestionId = 'Q2'

我假设XNumber1是Q1的结果,而Xnumber2是Q2的结果。

答案 1 :(得分:0)

这是实现预期结果的一种方法。但是,它依赖于知道只有xNumber abc和abc12是值。如果不是这种情况,则可能需要动态支点。

SELECT product, max(case when XNumber = 'abc' then xNumber end) as XNumber1, 
                max(Case when xNumber = 'abc12' then xNumber end) as xNumber2
FROM MyTable
GROUP BY Product

问题是SQL需要知道在编译SQL时结果中有多少列。由于列数可能取决于数据本身(2行对5行),因此无法完成请求。使用动态SQL,您可以找出行数,然后将这些值作为列名传递,这就是动态SQL的工作原理。

答案 2 :(得分:0)

这将为您提供两列,第一列将是产品,第二列将是逗号分隔的xNumbers列表。

SELECT DISTINCT T.Product,
xNumbers = Stuff((SELECT DISTINCT  ', ' + T1.XNumber 
                        FROM MyTable T1
                        WHERE t.Product = T1.Product
                        FOR XML PATH ('')),1,1,'')        
FROM MyTable T 

为了得到你想要的东西,我们需要知道将有多少列,命名它们,以及如何确定哪个值进入哪个列

答案 3 :(得分:0)

如果您对所有ID的Q1和Q2都没有答案,这将最有效

SELECT a.Product, b.XNumber as XNumber1, c.XNumber as XNumber2
FROM (SELECT DISTINCT Product FROM MyTable) a
LEFT JOIN MyTable b ON a.Product = b.Product AND b.QuestionID = 'Q1'
LEFT JOIN MyTable c ON a.Product = c.Product AND c.QuestionID = 'Q2'

答案 4 :(得分:0)

在当前的代码中使用了rank(),我们一直在工作。因此,您可以想到这个有趣的变体。

使用rank获取第1,第2和第3个可能的项标识符,然后将它们分组以创建模拟的pivot

DECLARE @T TABLE (PRODUCT VARCHAR(50), XNumber VARCHAR(50)) INSERT INTO @T VALUES ('Bat','0-12345-98765-6'), ('Bat','0-12345-98767-2'), ('Bat','0-12345-98768-1'), ('Ball','0-12345-98771-6'), ('Ball','0-12345-98772-7'), ('Ball','0-12345-98777-9'), ('Hat','0-12345-98711-6'), ('Hat','0-12345-98712-3'), ('Tee','0-12345-98465-1')

SELECT PRODUCT, MAX(CASE WHEN I = 1 THEN XNumber ELSE '' END) AS Xnumber1, MAX(CASE WHEN I = 2 THEN XNumber ELSE '' END) AS Xnumber2, MAX(CASE WHEN I = 3 THEN XNumber ELSE '' END) AS Xnumber3 FROM ( SELECT PRODUCT, XNumber, RANK() OVER(PARTITION BY PRODUCT ORDER BY XNumber) AS I FROM @T ) AS DATA GROUP BY PRODUCT