[英]SQL IN statement - keep duplicates when returning results
我有一個像這樣的SQL查詢:
SELECT * FROM prices WHERE item IN ('item1', 'item2', 'item2', 'item3');
注意重復值'item2'。 我希望查詢返回該項的值多次出現在IN子句中。 默認情況下,它只返回一次。 我怎樣才能做到這一點?
然后你需要使用left join
:
select p.*
from (select 'item1' as item union all select 'item2' union all
select 'item2' union all select 'item3'
) i left join
prices p
on i.item = p.item;
SQL將IN
列表中的項目視為一個集合,忽略重復項。
在支持表值參數(TVP)的數據庫中,您可以使用TVP上的內部聯接替換IN
,但MySQL不提供它們。
另一種方法是使用IN
列表中的項填充臨時表,並使用內部聯接查詢它:
CREATE TEMPORARY TABLE InList (item varchar(10));
INSERT INTO InList(item) VALUES ('item1');
INSERT INTO InList(item) VALUES ('item2');
INSERT INTO InList(item) VALUES ('item2');
INSERT INTO InList(item) VALUES ('item3');
現在您的查詢將如下所示:
SELECT p.*
FROM prices p
INNER JOIN InList i ON i.item = p.item
由於連接產生笛卡爾積,因此price
行將重復多次,因為它們在臨時InList
表中列出。
你不能。 該查詢將返回item1
在表中顯示的次數,而不是它在查詢中出現的次數
您可以做的一件事是查找每個項目的出現次數,然后檢查您想要的數字,如下所示:
SELECT * FROM prices po WHERE
EXISTS (SELECT item FROM prices pi
WHERE pi.item = po.item
GROUP BY item
HAVING ( (COUNT(item) = 1 AND item in ('item1', 'item3') )
OR ( (COUNT(item) = 2 AND item = 'item2' )
)
由於這將返回所有匹配項,因此您將在結果中顯示每個項目在價格表中顯示的次數。
關於戈登答案的兩個注釋(因為我是新來的,不能在那里評論):( 1)左外連接可能導致返回空值。 如果item3根本沒有出現在價格中,那么結果中將出現null。 您可以使用過濾器(其中p.item不為null)來刪除這些空值。 (2)如果item2在price表中只出現一次,則join將仍然在結果中出現兩次。 連接不執行檢查item2在價格中出現兩次,它只是將它連接兩次到FROM子句中創建的常量表。
SELECT *
FROM PRICE
WHERE ITEM IN (item1, item2, item3)
UNION ALL
SELECT *
FROM PRICE
WHERE ITEM = item2
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.