2012-09-19 25 views
2

我有一個包含大約300,000行產品信息的數據庫。
我需要與重複的UPC(COUNT(UPC)> 1),其中至少一個結果描述的特定的字符串匹配檢索行(‘裏德’,例如。)MySQL:如何檢索具有重複字段的所有行,匹配任何匹配行中的某個字段上的LIKE

對於例如,下面的行會都被選中(DESC,UPC對)

Deer D7394 62226173 
Reed R2536 62226173 
Deer D7217 62226173 

但沒有

Deer D0173 62278389 
Deer D7289 62278389 
Deer D9272 62278389 

這是我的工作查詢與:

SELECT a.desc, a.upc, a.sku, a.short_description 
FROM inventory a 
JOIN 
    (SELECT upc, desc 
    FROM inventory 
    GROUP BY upc 
    HAVING COUNT(upc) > 1) b 
ON a.upc = b.upc 
WHERE ((a.desc LIKE '%Reed%') OR (b.desc LIKE '%Reed%')) 
AND a.upc != '' 
AND a.upc != 0 
ORDER BY upc; 

我是比較新的MySQL,但這似乎應該工作。但是,某些結果未能返回不匹配的行(即將返回Reed R2536,但不包括Deer D7394)。

任何有識之士將不勝感激!

回答

3

Brian的group_concat方法將起作用,當重複的數量很少時,但它不會在默認情況下失敗。你永遠不會知道;你只會缺少應該存在的行。

你想要做的是選擇所有至少有一個描述匹配的UPC(並且存在重複項),然後從該列表中選擇匹配每個UPC的所有行。

如果組中的所有物品通過UPC,那麼你就可以標註每一個具有計數和標誌是否有匹配的描述:

SELECT upc, COUNT(*) c, MAX(`desc` LIKE '%Reed%') desc_matches 
FROM inventory 
GROUP BY upc 

(這需要的事實,即布爾運算符,如LIKE,實際上返回0爲false,1爲true。取最大值該列的告訴你任何行是否匹配)

然後,您可以根據您的標準篩選列表,只獲取的UPC你有興趣:

SELECT upc, COUNT(*) c, MAX(`desc` LIKE '%Reed%') desc_matches 
FROM inventory 
GROUP BY upc 
HAVING desc_matches = 1 AND c > 1 

一旦你的列表,你想看到所有與這些UPC匹配的產品。你可以通過一個簡單的(不是外部)連接來實現:

SELECT a.desc, a.upc, a.sku, a.short_description 
FROM inventory a 
JOIN 
    (SELECT upc, COUNT(*) c, MAX(`desc` LIKE '%Reed%') desc_matches 
     FROM inventory 
     GROUP BY upc 
     HAVING desc_matches = 1 AND c > 1 
    ) b USING (upc) 
+0

我剛剛測試了這兩個 - 我錯過了什麼,或者他們只滿足文本匹配標準?我對這種方法感興趣,但它也需要檢查重複項。 – Sara

+0

你是對的 - 當我讀到它時我錯過了。我重新查詢了這些項目。 –

+0

謝謝!我不知道你可以這樣使用'LIKE',而且這看起來會捕獲幾行並且有很多重複的行,而另一個查詢卻錯過了。我已經更新了接受的答案。 – Sara

0

很難說沒有測試,但嘗試:

SELECT a.desc, a.upc, a.sku, a.short_description 
FROM inventory a 
OUTER RIGHT JOIN 
    (SELECT upc 
    FROM inventory 
    GROUP BY upc 
    HAVING COUNT(upc) > 1) b 
ON a.upc = b.upc 
WHERE ((a.desc LIKE '%Reed%') OR (b.desc LIKE '%Reed%')) 
AND a.upc != '' 
AND a.upc != 0 
ORDER BY upc; 

的關鍵是OUTER RIGHT JOIN。請參閱文章:http://www.codeproject.com/Articles/33052/Visual-Representation-of-SQL-Joins

另外,您只需要從內部SELECT查詢中返回upc。

+0

謝謝!但是,當我從內部的'SELECT'中刪除desc時,我得到「unknown field b.desc」。 此外,語法錯誤提示我指定一個外部連接的類型,所以我目前正在運行'左外部連接'。不幸的是,在這種情況下需要很長的時間才能實踐(表中的行數> 300,000)。 – Sara

1

另一種可能的方式做到這一點,假設你沒有太多的重複記錄是:

select * from inventory i 
    join (
     SELECT upc 
      FROM inventory 
      GROUP BY upc 
      HAVING COUNT(upc) > 1 
       and group_concat(`desc`) like '%reed%') as available_upc 
      on available_upc.upc = i.upc 

這是假設你的表看起來像:

CREATE TABLE inventory(
    sku CHAR(32) NOT NULL, 
    `desc` CHAR(32) NOT NULL, 
    upc CHAR(32) NOT NULL, 
    short_description CHAR(32) NOT NULL, 
    PRIMARY KEY (sku) 
); 

insert into inventory values ('D7394','Deer','62226173','Small Deer'); 
insert into inventory values ('R2536','Reed','62226173','Small Reed'); 
insert into inventory values ('D7217','Deer','62226173','Large Deer'); 


insert into inventory values ('D0173','Deer','62278389','Small Deer'); 
insert into inventory values ('D7289','Deer','62278389','Small Reed'); 
insert into inventory values ('D9272','Deer','62278389','Large Deer'); 
+0

這似乎工作,非常感謝你! – Sara

相關問題