从连接表中选择第N个子项

时间:2014-12-01 14:28:24

标签: sql-server tsql

我有一个TSQL查询,一个基本的一对多类型关联,看起来像这样:

SELECT  Palette.Palette_ID
        Colour.Name
FROM    Palette
INNER JOIN Colour
    ON Palette.Palette_ID = Colour.Palette_ID

这导致了一个相当标准的数据集,因此每个调色板可以有与其相关的未知数量的颜色,可能没有,可能是20,可能更多:

Palette ID | Colour Name
========================
1          | Red
1          | Blue
2          | Yellow
2          | Red
2          | Orange
3          | Pink
4          | Red
4          | Yellow

我正在寻找一个查询,它给了我一个有点数据透视的数据集,有3列给我带有Pallette的前3种颜色,如下所示:

Palette ID | First Colour | Second Colour | Third Colour
========================================================
1          | Red          | Blue          | NULL
2          | Yellow       | Red           | Orange
3          | Pink         | NULL          | NULL
4          | Red          | Yellow        | NULL

我理解如何使用GROUP BY和SELECT MIN()MAX()来获取给定调色板的第一个和最后一个颜色选择,但是我不知道如何去做像这样选择第n个连接的行。

任何建议都将不胜感激。我花了太多时间使用ORM,而且我与SQL完全脱节。

3 个答案:

答案 0 :(得分:0)

使用ROW_NUMBER()函数: http://msdn.microsoft.com/en-GB/library/ms186734.aspx

在您的查询中,类似

SELECT  Palette.Palette_ID,
        Colour.Name,
ROW_NUMBER ( ) 
        OVER ( PARTITION BY Palette.Palette_ID ORDER BY Colour.Name ) row_num
FROM    Palette
INNER JOIN Colour
    ON Palette.Palette_ID = Colour.Palette_ID

这应该为每个调色板的每个行添加一个序列号,在调色板更改时重新初始化。在您的情况下,您似乎不是按颜色名称排序,因此您可能需要调整订单条款。

答案 1 :(得分:0)

以下内容 - 使用ROW_NUMBER函数。

WITH c AS (
  SELECT 
    Palette_ID, 
    Name, 
    ROW_NUMBER OVER (PARTITION BY Palette_ID ORDER BY Name) AS rn
  FROM Colour
)
SELECT 
  p.Palette_ID, 
  c1.Name AS [First Colour],
  c2.Name AS [Second Colour],
  c3.Name AS [Third Colour]
FROM Palette AS p
  LEFT JOIN c AS c1 ON p.Palette_ID = c1.Palette_ID AND c1.rn = 1
  LEFT JOIN c AS c2 ON p.Palette_ID = c2.Palette_ID AND c2.rn = 2
  LEFT JOIN c AS c3 ON p.Palette_ID = c3.Palette_ID AND c3.rn = 3

答案 2 :(得分:0)

使用Pivot 转置行到列。

CREATE TABLE #test1
  (Palette_ID  INT,Colour_Name VARCHAR(50))

INSERT #test1
VALUES (1,'Red'),(1,'Blue'),(2,'Yellow'),
       (2,'Red'),(2,'Orange'),(3,'Pink'),
       (4,'Red'),(4,'Yellow')

SELECT Palette_ID,
       [1 color] First_Color,
       [2 color] Second_Color,
       [3 color] Third_Color
FROM   (SELECT CONVERT(VARCHAR(10), Row_number() OVER (partition BY Palette_ID ORDER BY Colour_Name))
               + ' Color' AS dd,
               *
        FROM   #test1) a
       PIVOT (Max(Colour_Name)
             FOR dd IN([1 color],
                       [2 color],
                       [3 color]))piv 
相关问题