SQL Server中3个不同列中每个分区对应的前3个级别

SQL Server中3个不同列中每个分区对应的前3个级别,sql,sql-server,sql-server-2008,sql-server-2012,Sql,Sql Server,Sql Server 2008,Sql Server 2012,下面是我在SQL Server中的表 ID NAME SALARY 10 A 10 10 B 5 10 C 20 10 D 20 11 E 40 11 F 40 11 G 30 11 H 50 12 I 50 12 J 35 我的目标是为每个ID添加其他六列第一

下面是我在SQL Server中的表

ID      NAME    SALARY
10      A       10
10      B       5
10      C       20
10      D       20
11      E       40
11      F       40
11      G       30
11      H       50
12      I       50
12      J       35
我的目标是为每个ID添加其他六列第一个值、第二个值、第三个值、第一个值、第二个值、第三个值。 输出应如下所示:

ID  NAME    SALARY R1   R2    R3     R1_name    R2_name    R3_name
10  A       10     5    10    20     B          A          C
10  B       5      5    10    20     B          A          C
10  C       20     5    10    20     B          A          C
10  D       20     5    10    20     B          A          C
11  E       40     30   40    40     G          E          F
11  F       40     30   40    40     G          E          F
11  G       30     30   40    40     G          E          F
11  H       50     30   40    40     G          E          F
12  I       50     35   50    NULL   J          I          NULL
12  J       35     35   50    NULL   J          I          NULL
以下是插入查询:

CREATE TABLE EMP(ID NVARCHAR(10), NAME NVARCHAR(20), SALARY MONEY)

INSERT INTO EMP
VALUES
(10, 'A', 10),(11, 'E',40 ),(10,'B',5),(11,'F',40),(12,'I',50)
,(10,'C',20),(11,'G',30),(12,'J',35),(10,'D',20),(11,'H',50)

提前谢谢。

很难看,但效果不错,你可以试试

DECLARE @EMP AS TABLE(ID NVARCHAR(10), NAME NVARCHAR(20), SALARY MONEY)

INSERT INTO @EMP
VALUES
(10, 'A', 10),(11, 'E',40 ),(10,'B',5),(11,'F',40),(12,'I',50)
,(10,'C',20),(11,'G',30),(12,'J',35),(10,'D',20),(11,'H',50)


;WITH temp AS
(
   SELECT e.* , row_number() over(partition by e.ID ORDER BY e.SALARY ASC) AS Rn
   FROM @EMP e
)
SELECT e.*, t1.SALARY AS R1, t1.Name AS R1_Name, t2.SALARY AS R2, t2.Name AS R2_Name, t3.SALARY AS R3, t3.Name AS R3_Name
FROM @EMP e
LEFT JOIN temp t1 ON e.ID = t1.ID AND t1.Rn  = 1
LEFT JOIN temp t2 ON e.ID = t2.ID AND t2.Rn  = 2
LEFT JOIN temp t3 ON e.ID = t3.ID AND t3.Rn  = 3
ORDER BY e.ID ASC

演示链接:

相当难看,但它可以工作,你可以试试

DECLARE @EMP AS TABLE(ID NVARCHAR(10), NAME NVARCHAR(20), SALARY MONEY)

INSERT INTO @EMP
VALUES
(10, 'A', 10),(11, 'E',40 ),(10,'B',5),(11,'F',40),(12,'I',50)
,(10,'C',20),(11,'G',30),(12,'J',35),(10,'D',20),(11,'H',50)


;WITH temp AS
(
   SELECT e.* , row_number() over(partition by e.ID ORDER BY e.SALARY ASC) AS Rn
   FROM @EMP e
)
SELECT e.*, t1.SALARY AS R1, t1.Name AS R1_Name, t2.SALARY AS R2, t2.Name AS R2_Name, t3.SALARY AS R3, t3.Name AS R3_Name
FROM @EMP e
LEFT JOIN temp t1 ON e.ID = t1.ID AND t1.Rn  = 1
LEFT JOIN temp t2 ON e.ID = t2.ID AND t2.Rn  = 2
LEFT JOIN temp t3 ON e.ID = t3.ID AND t3.Rn  = 3
ORDER BY e.ID ASC

演示链接:

我们实际上可以通过对每个ID的工资进行排序的CTE进行单个连接来实现您所需的输出

输出:

此处演示:


实际上,我们可以通过对每个ID的工资进行排序的CTE进行单个连接来实现您想要的输出

输出:

此处演示:


我认为您不应该将这些值硬编码到表中,因为如果在任何时候,这些值发生变化,您都需要调整整个表。从技术上讲,这也是数据的复制,您应该尽量避免。相反,我认为您应该创建一个视图。我不认为您应该将这些值硬编码到表中,因为如果值在任何时候发生更改,您都需要调整整个表。从技术上讲,这也是数据的复制,您应该尽量避免。相反,我认为您应该创建一个视图。
;WITH TOUpdate AS
(
  SELECT ID,
         MAX(case when RN=1 THEN SALARY ELSE 0 END) AS R1,
         MAX(case when RN=2 THEN SALARY ELSE 0 END) AS R2,
         MAX(case when RN=3 THEN SALARY ELSE 0 END) AS R3,
         MAX(case when RN=1 THEN Name ELSE NULL END) AS R1_Name,
         MAX(case when RN=2 THEN Name ELSE NULL END) AS R2_Name,
         MAX(case when RN=3 THEN Name ELSE NULL END) AS R3_Name
  FROM(
        SELECT *,ROW_NUMBER() OVER (PARTITION BY ID ORDER BY SALARY) AS RN
        FROM @EMP
                  ) X
WHERE X.RN<4
GROUP BY ID
             )

SELECT *
FROM @EMP E
INNER JOIN TOUpdate U
ON E.ID=U.ID