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中文網其他相關文章!