我试图通过考虑下一个和之前的记录来订购特定的查询,但我似乎无法完成它。我想通过数字和字母来订购,但是,例如,如果数字1的最后一个字母等于数字2中的一个字母,我想更改顺序,以便该字母与以下字母匹配记录。
Create script and SQL fiddle demo
create table Parent (
id [bigint] IDENTITY(1,1),
number bigint NOT NULL,
PRIMARY KEY (id)
)
GO
create table Child (
id [bigint] IDENTITY(1,1),
parentId BIGINT,
letter VARCHAR(1) NOT NULL,
PRIMARY KEY (id),
UNIQUE (parentId, Letter),
FOREIGN KEY (parentId) REFERENCES Parent(id)
)
GO
INSERT Parent (number) VALUES (1)
INSERT Parent (number) VALUES (2)
INSERT Parent (number) VALUES (3)
INSERT Child (parentId, letter) VALUES (1, 'A')
INSERT Child (parentId, letter) VALUES (1, 'C')
INSERT Child (parentId, letter) VALUES (2, 'B')
INSERT Child (parentId, letter) VALUES (2, 'C')
INSERT Child (parentId, letter) VALUES (3, 'B')
INSERT Child (parentId, letter) VALUES (3, 'D')
当前查询
目前我正在使用此查询进行排序:
SELECT P.number, C.letter
FROM Child C
JOIN Parent P ON C.parentId = P.id
ORDER BY P.number, C.letter
当前结果集
number letter
-------------------- ------
1 A
1 C
2 B
2 C
3 B
3 D
预期结果集
为了澄清我实际想做什么,这里是预期的结果集(切换了2号C和B)。
number letter
-------------------- ------
1 A
1 C
2 C --switched
2 B --switched
3 B
3 D
其他要求和问题
有人能指出我正确的方向如何做到这一点?
答案 0 :(得分:6)
你可以这样做。
ROW_NUMBER()
和PARTITION BY
id
的最后一条记录与下一个id
的第一条记录相匹配。 LEFT JOIN
并使用CASE
或ISNULL
为信件匹配的id
记录设置更高的优先级<强>查询强>
;WITH CTE AS
(
SELECT id,ParentID,letter,
ROW_NUMBER()OVER(PARTITION BY parentId ORDER BY ID) first_element,
ROW_NUMBER()OVER(PARTITION BY parentId ORDER BY ID DESC) Last_element
FROM Child
), CTE2 AS
(
SELECT c1.id,c1.parentid,c1.letter,c2.parentid as c2parentid
FROM CTE c1
INNER JOIN CTE c2
ON c1.last_element = 1
AND c2.first_element = 1
AND c1.id +1 = c2.id
), CTE3 AS
(
SELECT C.parentid,C.id
FROM CTE2
INNER JOIN child C ON CTE2.c2parentid = C.parentid
AND C.letter = CTE2.letter
)
SELECT P.number, C.letter
FROM Child C
JOIN Parent P ON C.parentId = P.id
LEFT JOIN CTE3 ON CTE3.id = C.id
ORDER BY P.number, ISNULL(CTE3.id,0) DESC, C.letter
<强>输出强>
number letter
1 A
1 C
2 C
2 B
3 B
3 D
修改强>
如果您的ids
不是连续的,则可以像这样更改CTE1
和CTE2
以使用ROW_NUMBER()OVER(ORDER BY ID) seq_id
。
;WITH CTE AS
(
SELECT id,ParentID,letter,
ROW_NUMBER()OVER(ORDER BY ID) seq_id,
ROW_NUMBER()OVER(PARTITION BY parentId ORDER BY ID) first_element,
ROW_NUMBER()OVER(PARTITION BY parentId ORDER BY ID DESC) Last_element
FROM Child
), CTE2 AS
(
SELECT c1.id,c1.parentid,c1.letter,c2.parentid as c2parentid
FROM CTE c1
INNER JOIN CTE c2
ON c1.last_element = 1
AND c2.first_element = 1
AND c1.seq_id + 1 = c2.seq_id
)
其余代码保持不变。