SQLite 在 returns 1 列的子查询中保留列 order/custom 排序顺序

SQLite preserve column order/custom sort order in subquery that returns 1 column

我想保留使用 UNION 收集列值的子查询的列顺序(细化我在此处提出的问题 )。下面的查询按键的升序对数字进行排序,我想不出一种方法来保留 Keys table 中的列顺序而不引入另一个属性。

一个最小的例子:

CREATE TABLE Keys(primary_id, id1, id2, id3);
CREATE TABLE Attr(id, attr1, attr2);

INSERT INTO Keys VALUES(1, 7, 2, 5);
INSERT INTO Keys VALUES(2, 6, 1, 3);
INSERT INTO Keys VALUES(3, 4, 2, 7);
INSERT INTO Attr VALUES(1, "a", "b");
INSERT INTO Attr VALUES(2, "c", "d");
INSERT INTO Attr VALUES(3, "e", "f");
INSERT INTO Attr VALUES(4, "g", "h");
INSERT INTO Attr VALUES(5, "i", "j");
INSERT INTO Attr VALUES(6, "k", "l");
INSERT INTO Attr VALUES(7, "m", "n");

SELECT *
FROM Attr
WHERE Attr.id IN (SELECT primary_id FROM Keys WHERE Keys.primary_id=2
                  UNION
                  SELECT id1 FROM Keys WHERE Keys.primary_id=2
                  UNION
                  SELECT id2 FROM Keys WHERE Keys.primary_id=2
                  UNION
                  SELECT id3 FROM Keys WHERE Keys.primary_id=2);

1|a|b
2|c|d
3|e|f
6|k|l

期望的输出保留 primary_id, id1, id2, id3:

的顺序
2|c|d
6|k|l
1|a|b
3|e|f

子查询本身我可以通过创建另一个属性来排序:

SELECT primary_id, 1 as sort FROM Keys WHERE Keys.primary_id = 2
UNION
SELECT id1, 2 as sort FROM Keys WHERE Keys.primary_id = 2
UNION
SELECT id2, 3 as sort FROM Keys WHERE Keys.primary_id = 2
UNION
SELECT id3, 4 as sort FROM Keys WHERE Keys.primary_id = 2
ORDER BY sort

但是外部查询只需要 1 列,所以这不是解决方案。谢谢你的想法!

使用 returns 2 列的 CTE 并将其连接到 table 而不是使用运算符 IN.
然后就可以使用sort列对结果进行排序:

WITH cte AS (
  SELECT primary_id AS id, 1 AS sort FROM Keys WHERE Keys.primary_id = 2
  UNION 
  SELECT id1, 2 AS sort FROM Keys WHERE Keys.primary_id = 2
  UNION 
  SELECT id2, 3 AS sort FROM Keys WHERE Keys.primary_id = 2
  UNION 
  SELECT id3, 4 AS sort FROM Keys WHERE Keys.primary_id = 2
)
SELECT DISTINCT a.*
FROM Attr a INNER JOIN cte c
ON c.id = a.id
ORDER BY c.sort;

参见demo

您可以加​​入 IN
并按 CASE.

排序
SELECT a.*
FROM Attr a
INNER JOIN Keys k
  ON k.primary_id = 2
 AND a.id IN (k.primary_id, k.id1, k.id2, k.id3)
ORDER BY 
 CASE a.id 
 WHEN k.primary_id THEN 0
 WHEN k.id1 THEN 1
 WHEN k.id2 THEN 2
 WHEN k.id3 THEN 3
 ELSE 9
 END
id attr1 attr2
2 c d
6 k l
1 a b
3 e f

演示 db<>fiddle here