2017-04-20 33 views
0

我是新來這個SQL世界。在我是一位開發人員,他在SQL &簡單連接方面的知識有限。我在編寫sql join時出現了一對多關係的問題。這裏是我的問題說 -1到很多與狀態檢查很多方面

舉例來說,如果我有一個客戶表:

id Name   address 
1 manoj  Japan 
2 Sunil  US 

並配有門票表:

id customerid  ticketstatus 
1 1    closed 
2 1    closed 
3 2    closed 
4 1    open 
5 2    closed 

現在我想以後參加的是:

id  customername  ticketstatus 
2   sunil   closed 

所以我只想要那些所有門票狀態的客戶已經關閉。

任何一個人都可以幫忙爲此寫作嗎?

回答

1

請嘗試以下...

SELECT id, 
     Name 
FROM Customer 
WHERE id NOT IN (SELECT customerid 
        FROM Tickets 
        WHERE ticketstatus <> 'closed' 
       ); 

本聲明列出了Customeridname,他們的id不會出現在對應於closed以外的狀態的customerid的列表(來自Tickets表格)中。

不需要加入,除非您希望顯示ticketstatus,即使它始終爲closed。在這種情況下,請嘗試以下方法...

SELECT Customer.id AS id, 
     Name, 
     ticketstatus 
FROM Customer 
JOIN Tickets ON Customer.id = Tickets.customerid 
WHERE id NOT IN (SELECT customerid 
        FROM Tickets 
        WHERE ticketstatus <> 'closed' 
       ) 
GROUP BY Customer.id; 

請注意額外字段被包括在輸出和執行JOIN。由於客戶可能擁有多個closedTicket,因此我還添加了GROUP BY Customer.id子句以將輸出減少爲每個Customer只有一個記錄。

如果您有任何問題或意見,請隨時發佈相應評論。

+0

這樣會得到根本沒有任何門票的顧客。 –

+0

「不需要加入」是不完全正確的,因爲NOT IN條件是一種連接形式(特別是ANTI-JOIN)。雖然這種形式確實比「標準」加入要便宜。然後:如果狀態永遠不能爲NULL,那麼NOT IN條件沒問題;如果它可以是NULL,那麼必須更加小心。 – mathguy

+0

mathguy,感謝您對('NOT')'IN'和各種類型的連接的有趣評論。我從來沒有真的這樣想過。另外,我同意你關於潛在的'NULL'問題的評論,儘管在這種情況下,我認爲'customerid'永遠不會有'NULL'值。 – toonice

0

試試這個: -

 Select distinct a.ID, a.Name as customername, b.ticketstatus 
      from 
      Customer a 
      inner join 
      Tickets b 
      on a.Id=b.CustomerId 
      where a.Id not in 
      (select CustomerId from 
      Tickets where ticketstatus <> 'closed' 
      ) 
      and b.ticketstatus='closed' 
      ; 

    OR 

    //With Same logic and different approach 

    Select distinct a.ID, a.Name as customername, b.ticketstatus 
     from 
     Customer a 

     inner join 

     (select CusotomerID,ticketstatus from Tickets 
     where ticketstatus='closed' 
     ) b 

     on a.Id=b.CustomerId 
     where a.Id not in 
     (select CustomerId from 
     Tickets where ticketstatus <> 'closed' 
     ) ; 
+0

這將獲得所有已關閉門票的客戶,但也將返回那些門票已關閉的門票。 –

+0

修正了它。很抱歉對於這個誤會。 –

+1

如果第三個「ticketstatus」存在或者被引入,這將返回不正確的結果集。由於該問題僅特別要求那些將所有'ticketstatus'值設置爲'closed'的客戶,您可以通過將where ticketstatus ='open''更改爲'where ticketstatus <>'關閉' '。 – toonice

0

你需要的是找到誰至少有一票,誰沒有票未關閉所有用戶:

SELECT c.id, c.name AS customername 
    FROM customers c 
WHERE EXISTS (SELECT 1 FROM tickets t 
       WHERE t.customerid = c.id) 
    AND NOT EXISTS (SELECT 1 FROM tickets t 
        WHERE t.customerid = c.id 
         AND t.ticketstatus != 'closed'); 

希望這有助於。

-2

您正在尋找這樣的事情:

select distinct a.customername, b.ticketstatus from table1 a 
join table2 b on a.id = b.customerid 
where b.ticketstatus = 'closed' 
+0

這會讓所有至少有一個「關閉」狀態的客戶 - 而不是OP要求的。 – mathguy

+0

這將返回所有擁有至少一個'Ticket'且''ticketstatus'''''的客戶,包括那些擁有'ticketstatus''' open'(或任何其他潛在'ticketstatus'值的'Ticket' )。 – toonice

+0

正在顯示'b.ticketstatus'嗎?我們知道它將永遠關閉。此外,我還建議同時顯示'a.id'字段(除非另有特別要求)作爲區分重複名稱的方式。例如你將如何處理兩個'約翰史密斯'?最後,根據問題的表格定義,'a.customername'應該讀取'a.Name'。您可以將'a.customername'更改爲'a.Name AS customername'以在輸出中顯示不同的名稱。 – toonice

1
的門票表

標準彙總(亞)查詢,隨後加入,以獲得客戶名稱:

with 
    customer (id, name, address) as (
     select 1, 'Manoj', 'Japan' from dual union all 
     select 2, 'Sunil', 'US' from dual 
    ), 
    tickets (id, customerid, ticketstatus) as (
     select 1, 1, 'closed' from dual union all 
     select 2, 1, 'closed' from dual union all 
     select 3, 2, 'closed' from dual union all 
     select 4, 1, 'open' from dual union all 
     select 5, 2, 'closed' from dual 
    ) 
-- END of test data (not part of the solution!) 
-- SQL query begins BELOW THIS LINE 
select s.id, c.name, 'closed' as ticketstatus 
from (
     select customerid as id 
     from  tickets 
     group by customerid 
     having min(ticketstatus) = 'closed' 
      and max(ticketstatus) = 'closed' 
     ) s 
     join customer c 
     on s.id = c.id 
; 

ID NAME TICKETSTATUS 
-- ----- ------------ 
2 Sunil closed 

這是假設ticketstatus不能NULL - 否則一些必須小心,因爲min()max()忽略空值。

0

我會加入客戶和工單以定義所需的結果集。 然後,我會排除所有未關閉門票的客戶。 如果任何值可能爲null,我在ticketstatus上使用了coalesce。

SELECT Distinct C.ID, C.Name as CustomerName, T.TicketStatus 
FROM Customer C 
INNER JOIN Tickets T 
on C.ID = T.customerID 
WHERE NOT EXISTS (SELECT 1 
        FROM TICKETS T2 
        WHERE coalesce(TicketStatus,'NULL') <> 'closed' 
        and T2.CustomerID = T.CustomerID) 
+0

正在顯示'T.Ticketstatus'嗎?我們知道它總是會被「關閉」。 – toonice

+0

這是一個問題,要問問題的鼻祖。這是他們預期的結果;所以這是我的答案。從技術上講,我可以避免加入門票和硬編碼「關閉」以獲得表現上的好處...但是*聳聳肩*如果他們改變顯示打開,那麼我將不得不改變兩個地方而不是一個。 – xQbert

+0

你和'印度。火箭'是一個很好的觀點。我相應地調整了我的答案。謝謝。 – toonice