Nic*_* N. 6 sql sql-server sql-server-2005
我试图通过考虑下一个和以前的记录来订购特定的查询,但我似乎无法完成它.我想通过数字和字母来订购,但是,例如,如果数字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')
Run Code Online (Sandbox Code Playgroud)
当前查询
目前我正在使用此查询进行排序:
SELECT P.number, C.letter
FROM Child C
JOIN Parent P ON C.parentId = P.id
ORDER BY P.number, C.letter
Run Code Online (Sandbox Code Playgroud)
当前结果集
number letter
-------------------- ------
1 A
1 C
2 B
2 C
3 B
3 D
Run Code Online (Sandbox Code Playgroud)
预期结果集
为了澄清我实际想做的事情,这里是预期的结果集(切换了2号的C和B).
number letter
-------------------- ------
1 A
1 C
2 C --switched
2 B --switched
3 B
3 D
Run Code Online (Sandbox Code Playgroud)
其他要求和问题
任何人都可以指出我正确的方向如何做到这一点?
你可以做这样的事情.
ROW_NUMBER()和标识每个父母的第一个和最后一个字母PARTITION BYid一个记录与下一个记录匹配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
Run Code Online (Sandbox Code Playgroud)
产量
number letter
1 A
1 C
2 C
2 B
3 B
3 D
Run Code Online (Sandbox Code Playgroud)
编辑
如果你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
)
Run Code Online (Sandbox Code Playgroud)
其余代码保持不变.
| 归档时间: |
|
| 查看次数: |
109 次 |
| 最近记录: |