[英]How to compare values in the same table
Filename||status
---------------
A|10
A|22
B|10
我的預期輸出是
B|10
我不應獲得文件名同時為10和22的輸出狀態
讓我們嘗試重述您的問題-您正在尋找狀態為10但狀態不為22的文件。一旦這樣表達問題,我們就可以使用exists
操作符輕松地將需求轉換為SQL :
SELECT *
FROM mytable a
WHERE status = 10 AND
NOT EXISTS (SELECT *
FROM mytable b
WHERE a.filename = b.filename AND
b.status = 22)
這是獲取結果的查詢:
WITH files AS(
SELECT 'A' AS filename, 10 AS status FROM dual UNION ALL
SELECT 'A' AS filename, 22 AS status FROM dual UNION ALL
SELECT 'B' AS filename, 10 AS status FROM dual UNION ALL
SELECT 'C' AS filename, 22 AS status FROM dual
)
SELECT filename, status
FROM files
WHERE filename NOT IN (
SELECT f1.filename
FROM files f1, files f2
WHERE f1.filename = f2.filename
AND f1.status = 22
AND f2.status = 10
);
我在表中添加了一條C記錄以檢查結果的正確性:
B 10
C 22
我不應獲得文件名同時為10和22的輸出狀態
換句話說,您可以具有狀態10
且沒有狀態22
行,也可以具有狀態22
且沒有狀態10
行。
這些查詢都不要求自聯接(它們都僅使用單個表掃描):
查詢 :
SELECT filename
FROM table_name
GROUP BY filename
HAVING ( COUNT( CASE status WHEN 10 THEN 1 END ) > 0
AND COUNT( CASE status WHEN 22 THEN 1 END ) = 0 )
OR ( COUNT( CASE status WHEN 10 THEN 1 END ) = 0
AND COUNT( CASE status WHEN 22 THEN 1 END ) > 0 );
輸出 :
FILENAME
--------
B
查詢 :
SELECT filename,
status
FROM (
SELECT t.*,
COUNT( CASE status WHEN 10 THEN 1 END )
OVER ( PARTITION BY filename ) AS s10,
COUNT( CASE status WHEN 22 THEN 1 END )
OVER ( PARTITION BY filename ) AS s22
FROM table_name t
WHERE status IN ( 10, 22 )
)
WHERE ( s10 > 0 AND s22 = 0 )
OR ( s10 = 0 AND s22 > 0 );
輸出 :
FILENAME STATUS
-------- ------
B 10
select Filename, min(status)
from [table_name]
group by Filename
having count(*) = 1
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.