[英]SQL XOR syntax isn't working
我注意到SQL SERVER EXPRESS中沒有XOR函數,因此我嘗試使用舊方法。
select NCLI
from CLIENT
where NCLI in (select NCLI
from COMMANDE
where NCOM in (select NCOM
from DETAIL
where ((NPRO = 'PA60' and NPRO <> 'PA45')
or (NPRO <> 'PA60' and NPRO = 'PA45'))))
現在,我不是數學專家,但據我所知,這應該給我提供僅訂購PA60或PA45而不訂購兩者的客戶數量(NCLI)。
結果是,它同時也為同時訂購兩者的人員提供了NCLI。
我再次檢查了我的舊數學課程,但是我不知道我在這里缺少什么。
甲where
條件被施加到單個行的列,而不是一組行。
條件:
可以使用group by子句解決:
select NCOM
from DETAIL
where NPRO IN ('PA60','PA45')
group by ncom
having count(distinct NPRO) = 1
僅當同一客戶可以在同一產品的detail
表中出現多次時,才需要使用唯一的distinct NPRO
。 否則, count(*)
也將起作用(但在此對distinct不會造成任何損害)。
上面的內容還將返回僅訂購PA60和其他產品的客戶。 如果您還想排除那些商品,則需要添加其他條件,以僅包括訂購商品數量等於商品數量的商品。
select NCOM
from DETAIL
where NPRO IN ('PA60','PA45')
group by ncom
having count(NPRO) = 1
and count(NPRO) = (select count(*)
from DETAIL d2
where d2.ncom = detail.ncom)
第二個條件也可以放在where
部分。
這個大的條件表達式只查看同一行中的數據,而不是每一行中的數據。
要執行所需的操作,您需要將表與其自身進行比較(JOIN),以便可以將每一行與其他行進行比較。 您可以使用排除聯接來執行此操作,在該聯接中您對表進行了左聯接以尋找某種條件,然后在where子句中通過將結果限制為NULL記錄來限制第二個表中某個字段的記錄,從而排除所有匹配項為NULL。
將此應用於您的問題,然后最里面的select查詢應如下所示:
select d1.NCOM
from DETAIL d1
left join DETAIL d2 on d2.NCOM = d1.NCOM and d2.NPRO <> d1.NPRO and d2.NPRO IN ('PA60', 'PA45')
where d1.NPRO IN ('PA60', 'PA45') and d2.NCOM IS NULL
有時您可以通過NOT EXISTS查詢而不是排除聯接來使它更好地執行,這一點也不值錢,但是我發現排除聯接更容易使用。
有了這一點,我們還應該將其他嵌套的select編寫為JOIN:
select cl.NCLI
from DETAIL d1
left join DETAIL d2 on d2.NCOM = d1.NCOM and d2.NPRO <> d1.NPRO and d2.NPRO IN ('PA60', 'PA45')
inner join COMMANDE cm on cm.NCOM = d1.NCOM
inner join CLIENT cl on cl.NCLI = cm.NCLI
where d1.NPRO IN ('PA60', 'PA45') and d2.NCOM IS NULL
根據表中的關系,您可能還需要為此添加一個distinct
的內容。
where NCOM in
(select NCOM from DETAIL where (
(NPRO = 'PA60' and NPRO <> 'PA45')
or (NPRO <> 'PA60' and NPRO = 'PA45')
)
您應該注意到, 為每行都處理了此WHERE
,這意味着您在子句中進行了多余的檢查。
每當NPRO
值保存PA60
,很明顯它不會在同一行中保存任何其他值(因為它不是ARRAY
)。
相同的規則適用於第二個條件。
你WHERE
其實看起來像
WHERE NCOM IN ( SELECT NCOM FROM DETAIL WHERE NPRO = 'PA60' OR NPRO = 'PA45' )
所以這個子查詢讓你NCOM
所有NPRO
是IN ('PA60','PA45')
而且每走一步,對於您想要的情況都會產生錯誤的結果。
有多種寫方法,但這可能是您所掌握的最簡單的方法。
SELECT NCLI
FROM CLIENT
WHERE NCLI IN (
SELECT NCLI
FROM COMMANDE
WHERE NCOM IN (
SELECT NCOM
FROM DETAIL
WHERE NPRO IN ('PA60', 'PA45')
AND NCOM NOT IN (
SELECT NCOM
FROM DETAIL
WHERE NPRO = 'PA60'
INTERSECT
SELECT NCOM
FROM DETAIL
WHERE NPRO = 'PA45'
)
)
)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.