[英]MySQL Join - Retrieve Left Table Rows only if all the Right Table Rows satisfies the WHERE clause
[英]Is there a way to limit rows in the right table of a left join to only be used once?
我試圖通過比較兩組數據來確定哪里存在一些數據丟失。
第一組數據包含一個截斷的非唯一條形碼,以及第二組的時間戳,我發現它也不是唯一的。 該表存儲在一個名為restoredData
的表中,因為該表是根據每晚創建的文本備份創建的。
第二組實際上是兩個表,其中一個稱為items
和itemss_archive
。 它們也具有非唯一的短條形碼和非唯一的時間戳。
restoredData
有2437910條記錄,每一個item
。 items
具有405,009, items_archive
具有1,589,768,總共1,994,777行。 因此,有至少443113個更多的記錄restoredData
比有在聯盟items
和items_archive
。
然而,每當我試圖LEFT JOIN
restoredData
到聯盟items
和items_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.