我想查詢資料庫以檢索名稱串列(名稱串列由用戶在 python 中提供)。我為這些姓名查找資料的標準如下:結果應該按照用戶提供的姓名串列的順序出現,所以如果我說...WHERE name = "Bob" OR name = "Alice"我希望 Bob 的結果首先出現,然后是 Alice 的結果。第二個標準是,如果對一個名字進行了兩次搜索,那么結果也應該包含兩次,所以我想要一種寫下來的方法,...WHERE name = 'Bob' OR name = 'Bob'以便結果也包含兩次 Bob 的行。
我想出了以下查詢:
SELECT * FROM
(SELECT *, 1 order_position FROM table WHERE name = 'Alice'
UNION ALL
SELECT *, 2 order_position FROM table WHERE name = 'Bob'
UNION ALL
SELECT *, 3 order_position FROM table WHERE name = 'Charlie'
UNION ALL
SELECT *, 4 order_position FROM table WHERE name = 'Dan'
) r ORDER BY order_position
這個查詢運行良好,但是當用戶提交數百個名字并且有數百個 UNION ALL 部分時,查詢變得極其緩慢。有沒有辦法在保持前面提到的兩個條件的同時提高查詢的性能?
uj5u.com熱心網友回復:
SELECT *, CASE name WHEN 'Alice' THEN 1
WHEN 'Bob' THEN 2
WHEN 'Charlie' THEN 3
WHEN 'Dan' THEN 4
END AS order_position
FROM table
WHERE name IN ('Alice', 'Bob', 'Charlie', 'Dan')
ORDER BY order_position;
或沒有額外的列:
SELECT *
FROM table
WHERE name IN ('Alice', 'Bob', 'Charlie', 'Dan')
ORDER BY CASE name WHEN 'Alice' THEN 1
WHEN 'Bob' THEN 2
WHEN 'Charlie' THEN 3
WHEN 'Dan' THEN 4
END;
附注。對于這個名字集ORDER BY name就足夠了。
這如何處理重復某些結果的要求?– 威廉·倫澤馬
如果需要重復,則必須將串列轉換為行集。
SELECT table.*
FROM table
JOIN ( SELECT 1 pos, 'Alice' name UNION ALL
SELECT 2 , 'Bob' UNION ALL
SELECT 3 , 'Charlie' UNION ALL
SELECT 4 , 'Bob' UNION ALL
SELECT 5 , 'Charlie' ) names USING (name)
ORDER BY names.pos
uj5u.com熱心網友回復:
不知何故,您必須使用order_position每個名稱的來構造名稱串列。
您可以在UNION ALL用于保留重復名稱的查詢中執行此操作,如下所示:
SELECT 'Alice' name, 1 order_position UNION ALL
SELECT 'Bob', 2 UNION ALL
SELECT 'Charlie', 3 UNION ALL
SELECT 'Dan', 4 UNION ALL
SELECT 'Alice', 1 UNION ALL
SELECT 'Bob', 2 UNION ALL
...............................
然后你所要做的就是將它加入到表中:
SELECT t.*
FROM tablename t
INNER JOIN (
SELECT 'Alice' name, 1 order_position UNION ALL
SELECT 'Bob', 2 UNION ALL
SELECT 'Charlie', 3 UNION ALL
SELECT 'Dan', 4 UNION ALL
SELECT 'Alice', 1 UNION ALL
SELECT 'Bob', 2 UNION ALL
...............................
) n ON n.name = t.name
ORDER BY n.order_position;
在 MySql 8.0 中,您可以使用 CTE:
WITH cte(name, order_position) AS (VALUES
ROW('Alice', 1), ROW('Bob', 2), ROW('Charlie', 3),
ROW('Dan', 4), ROW('Alice', 1), ROW('Bob', 2),
...................................................
)
SELECT t.*
FROM tablename t INNER JOIN cte c
ON c.name = t.name
ORDER BY c.order_position;
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/337175.html
