首頁 >資料庫 >mysql教程 >FIND_IN_SET() 與 IN():何時應將每個值用於逗號分隔值?

FIND_IN_SET() 與 IN():何時應將每個值用於逗號分隔值?

DDD
DDD原創
2024-12-25 21:35:16902瀏覽

FIND_IN_SET() vs. IN(): When Should I Use Each for Comma-Separated Values?

FIND_IN_SET() 與IN():揭開查詢難題

在資料庫查詢領域,了解不同函數之間的細微差別是函數至關重要的。在比較 FIND_IN_SET() 和 IN() 時,尤其是在查詢儲存為逗號分隔字串的值時,就會出現這樣的差異。

查詢差異

考慮兩個表: “orders”的列“attachedCompanyIDs”包含逗號分隔的公司標識符,“company”的列包含“companyID”列和相應的公司名稱。以下查詢使用FIND_IN_SET() 有效檢索與訂單關聯的公司名稱:

SELECT name
FROM orders, company
WHERE orderID = 1
AND FIND_IN_SET(companyID, attachedCompanyIDs)

但是,使用IN() 的類似查詢會產生意外結果:

SELECT name
FROM orders, company
WHERE orderID = 1
AND companyID IN (attachedCompanyIDs)

隱藏的陷阱

根本原因在於MySQL如何處理將AttachedCompanyID轉換為整數時的逗號分隔值。轉換會截斷第一個非數字處的數字,從而有效地將字串減少為第一個逗號分隔值。

例如,將attachedCompanyIDs 設定為“1,2,3”,IN() 查詢會錯誤變成:

companyID IN (1)

這解釋了為什麼IN() 查詢只傳回第一個公司名稱,而FIND_IN_SET()傳回所有公司名稱三.

克服限制

要解決此問題,請考慮適當處理逗號分隔字串的替代方法。在 PostgreSQL 中,可以使用陣列:

SELECT name
FROM orders
JOIN company
ON companyID = ANY(('{' || attachedCompanyIDs || '}')::INT[])
WHERE orderID = 1

不幸的是,MySQL 中不支援陣列。對於有限數量的值(例如少於 5 個),可以使用交叉連接和字串操作來解決:

SELECT name
FROM orders
CROSS JOIN
(
SELECT 1 AS pos
UNION ALL
SELECT 2 AS pos
UNION ALL
SELECT 3 AS pos
UNION ALL
SELECT 4 AS pos
UNION ALL
SELECT 5 AS pos
) q
JOIN company
ON companyID = CAST(NULLIF(SUBSTRING_INDEX(attachedCompanyIDs, ',', -pos), SUBSTRING_INDEX(attachedCompanyIDs, ',', 1 - pos)) AS UNSIGNED)

以上是FIND_IN_SET() 與 IN():何時應將每個值用於逗號分隔值?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn