2014-12-03 30 views
0

我注意到SQL SERVER EXPRESS中沒有XOR函數,所以我試圖用舊的方式來做。SQL 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')))) 

現在,我不是一個數學親但是從我所知道的,這應該給我的客戶(NCLI),只有訂購PA60或PA45而不是他們兩個人的數目。

其結果是它也給定了兩個人的NCLI。

我再次檢查了我的老數學課程,但我不知道我在這裏錯過了什麼。

+0

我會用NOT IN不是<> – gpullen 2014-12-03 15:34:02

+0

THX但是,這並不工作,要麼 – 2014-12-03 15:38:42

回答

0
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')

如果你想要的話,每走一步都會產生錯誤的結果。

1

那麼大的條件表達式只能看中相同的行的數據,而不是每一行。

要做你想做的事情,你需要比較(JOIN)表與自身,以便每一行都可以與其他行進行比較。您可以使用排除連接來完成此操作,您可以在其中對要查找某種情況的表執行左連接,然後在where子句中通過將結果限制爲來自第二個表的字段的NULL記錄來排除所有匹配項不應該是NULL。

應用給你的問題,然後最裏面選擇查詢應該是這樣的:

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 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了這一點。

2

A where條件應用於單行的列而不是一組行。

條件:

客戶端(NCLI),只有訂購PA60或PA45而不是他們兩個。

可以使用一組由子句來解決:

select NCOM 
from DETAIL 
where NPRO IN ('PA60','PA45') 
group by ncom 
having count(distinct NPRO) = 1 

distinct NPRO僅必要的,如果相同的客戶端可以出現在detail表一次以上相同的產品。否則,count(*)也會這樣做(但這裏的區別不會造成任何傷害)。

上面還將返回客戶訂購(僅)PA60和其他東西。如果你也想排除那些你需要添加另一個條件只包括那些訂購產品的數量等於第二個條件也可以放入where部分的

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) 

數量。

0

有幾種方法可以寫出來,但這可能是您擁有的最直接的方法。

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' 
       ) 
     ) 
    ) 
+0

這是肯定的就是我正在尋找最接近的代碼,但它仍然葉一客戶端同時訂購。我正在尋找原因。 – 2014-12-03 16:07:16