簡體   English   中英

從2個MySQL表中選擇非重復記錄

[英]Select non-duplicated records from 2 MySQL tables

我有2張桌子,即:1. downloadtickets 2. redeemedtickets

每個表均具有“ ticketid”屬性。

我想找到下載票證但沒有兌現票證的人-本質上是找到非重復的(唯一)票證ID。

我的查詢(PHP)如下:

$sql = "
SELECT ticketid 
FROM (
  SELECT ticketid 
  FROM downloadedtickets 
  UNION ALL 
  SELECT ticketid 
  FROM redeemedtickets
)
GROUP BY ticketid 
HAVING COUNT(*) = 1";

我沒有得到任何輸出。

一個好的方法是左連接,並測試NULL。

SELECT d.ticketid
  FROM downloadedtickets d 
  LEFT JOIN redeemedtickets r USING(ticketid)
 WHERE r.ticketid IS NULL

LEFT JOIN操作為每個下載的票證及其贖回創建一個結果行。 在沒有兌換的地方,redeemed.ticketid為NULL,因此此查詢使用WHERE僅選擇那些項目。

您應該指定並匯總要計數的字段。 見下文:

$sql = "SELECT COUNT(ticketid)ticketid FROM downloadedtickets UNION ALL SELECT ticketid FROM redeemedtickets GROUP BY ticketid HAVING COUNT(ticketid) = 1";

我將使用NOT EXISTSNOT INLEFT JOIN來解決這個問題。 這是后者的版本:

select d.*
from downloadedtickets d left outer join
     redeemedtickets r
     on d.ticketid = r.ticketid
where r.ticketid is null;

您的查詢似乎應該返回指定的結果。 關於您獲得的結果(無行)的一種可能解釋是,沒有任何未贖回的下載票證。

該查詢似乎認為ticketid在UNIQUE downloadedtickets表,以及獨特的redeemedtickets表...這也許是事實,但我們沒有從我們提供的規格信息。 (如果不是這種情況,那么ticketid來自downloadedtickets表的ticketid的COUNT(*)可能大於1。

ticketid是用於“匹配”兩個表中的行的右列嗎? 我們假設是這樣,因為這就是您的查詢所使用的。 (如果不是,那也可以解釋您得到的結果。)

您的查詢具有以下形式(更易於閱讀):

SELECT t.ticketid 
  FROM ( SELECT d.ticketid
           FROM downloadedtickets d
          UNION ALL
         SELECT r.ticketid
           FROM redeemedtickets r
       ) t
 GROUP BY t.ticketid
HAVING COUNT(*) = 1

我們注意到,有潛力,這種查詢可以返回ticketid為連續redeemedtickets不在downloadedtickets 可以保證不會發生這種情況,但是再次說明,規范中沒有該信息。

對於大型集合,實現該內聯視圖可能會很昂貴。

就個人而言,我更喜歡使用具有更有效的“反聯接”模式的查詢:

SELECT d.ticketid
  FROM downloadedtickets d
  LEFT
  JOIN redeemedtickets r 
    ON r.ticketid = d.ticketid
 WHERE r.ticketid IS NULL
 ORDER BY d.ticketid

從本質上講,這表示要從downloadedtickets返回所有行,以及從已redeemed ticket中返回的所有“匹配”行。 LEFT關鍵字使它成為“外部”聯接,因此無論左側表中是否有匹配的行,我們都從左側表中獲取所有行。 訣竅是WHERE子句中的謂詞,它過濾掉所有具有匹配項的行。 (如果有一場比賽,我們都保證ticketidredeemedtickets將非NULL。所以,這將有從該表中的NULL值的唯一的行會從行downloadedtickets這並沒有匹配。

這種查詢可以高效使用索引redeemedtickets與領先的列ticketid

這不是返回指定結果的唯一查詢,還有其他查詢模式可以返回等效結果。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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