簡體   English   中英

有沒有一種方法可以限制左聯接的右表中的行只能使用一次?

[英]Is there a way to limit rows in the right table of a left join to only be used once?

我試圖通過比較兩組數據來確定哪里存在一些數據丟失。

第一組數據包含一個截斷的非唯一條形碼,以及第二組的時間戳,我發現它也不是唯一的。 該表存儲在一個名為restoredData的表中,因為該表是根據每晚創建的文本備份創建的。

第二組實際上是兩個表,其中一個稱為itemsitemss_archive 它們也具有非唯一的短條形碼和非唯一的時間戳。

restoredData有2437910條記錄,每一個item items具有405,009, items_archive具有1,589,768,總共1,994,777行。 因此,有至少443113個更多的記錄restoredData比有在聯盟itemsitems_archive

然而,每當我試圖LEFT JOIN restoredData到聯盟itemsitems_archive ,我得到2437910個匹配,搜索其中LEFT JOIN為空即那里是在項目+ items_archive沒有匹配的記錄,我得到0我的計數已經嘗試同時加入條形碼和時間戳,並且兩者都具有相同的結果。

這肯定是由於我所有可用鍵上的非唯一性。 但是,如果我能夠只允許從我行(SELECT t_stamp, barcode FROM items UNION ALL SELECT t_stamp, barcode FROM items_archive) as allItems只使用一次的加入,即,使得它無法比擬的,在多件事情restoredData ,我認為它可以為我提供我實際上正在尋找的信息,這些記錄是通過文本記錄的,但由於item和items_archive表而丟失了。

有沒有辦法在SQL中做到這一點? 還是我必須以編程方式使用python來執行此操作,逐行通過restoredData查找,找到匹配項,如果有匹配項,將其刪除,使其無法再次使用?

另一件事,我知道這不可能是正確的,因為在我的項目和items_archive表匹配,我有一種特殊的條形碼“NO_READ”期間的錯誤讀取條形碼即發生,但沒有這樣的值在整體中restoredData

我正在使用MySQL 5.6。

以供參考

restoredData table, 2,437,910 records
barCode (Varchar(13), non-unique), t_stamp (Datetime, non-unique)

items and items_archive table 1,994,777 records total
barCode (Varchar(13), non-unique), t_stamp (Datetime, non-unique)

舉個例子,我可以有條形碼1,timestamp1出現在我的4倍restoredData只有一次在我的items + items_archive表和結果,因為它代表是這個

 restoredData                 items+items_archive
 barcodeCol  t_stampCol       barcode2Col  t_stamp2Col
 barcode1    timestamp1       barcode1     timestamp1             
 barcode1    timestamp1       barcode1     timestamp1             
 barcode1    timestamp1       barcode1     timestamp1             
 barcode1    timestamp1       barcode1     timestamp1             

我想要的是這個

 restoredData                 items+items_archive
 barcodeCol  t_stampCol       barcode2Col  t_stamp2Col
 barcode1    timestamp1       barcode1     timestamp1             
 barcode1    timestamp1       NULL         NULL             
 barcode1    timestamp1       NULL         NULL             
 barcode1    timestamp1       NULL         NULL

我能想到的唯一方法是用索引創建一些臨時表,然后使用索引來創建排名,以便可以使用它在兩個數據集之間創建唯一列:

CREATE TEMPORARY TABLE items_full (t_stamp datetime, barcode varchar(13), idx int NOT NULL AUTO_INCREMENT)

CREATE TEMPORARY TABLE restored_data (t_stamp datetime, barcode varchar(13), idx int NOT NULL AUTO_INCREMENT)

Insert into items_full
SELECT t_stamp, barcode FROM items 
UNION ALL 
SELECT t_stamp, barcode FROM items_archive

Insert into restored_data
SELECT t_stamp, barcode FROM restoreddata


Select t_stamp, barcode, DENSE_RANK() OVER (Partition By barcode, t_stamp order by idx) as myrank from items_full bb

left join 

(select t_stamp, barcode, DENSE_RANK() OVER (Partition By barcode, t_stamp order by idx) as myrank from restored_data) aa 

on bb.t_stamp=aa.t_stamp and bb.barcode=aa.barcode and bb.myrank=aa.myrank

where aa.t_stamp is null

我將從數數開始。 如果每個條形碼和時間戳的計數不匹配,則必須檢查相關記錄。

select
  r.barcode,
  r.t_stamp,
  r.cnt as recover_count,
  i.cnt as itemtables_count
from
(
  select barcode, t_stamp, count(*) as cnt
  from restoreddata
  group by barcode, t_stamp
) r
left join
(
  select barcode, t_stamp, count(*) as cnt
  from
  (
    select barcode, t_stamp from items
    union all
    select barcode, t_stamp from items_archive
  ) both
  group by barcode, t_stamp
) i on  i.barcode = r.barcode 
    and i.t_stamp = r.t_stamp
    and i.cnt <> r.cnt;

暫無
暫無

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

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