簡體   English   中英

SQL XOR語法不起作用

[英]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所有NPROIN ('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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM