2

約 300,000 行の製品情報を含むデータベースがあります。重複する UPC (COUNT(upc) > 1) を含む
行を取得する必要があり、結果の説明の少なくとも 1 つが特定の文字列 (たとえば、「Reed」) と一致します。

たとえば、次の行がすべて選択されます (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 は返されません)。

どんな洞察も大歓迎です!

4

3 に答える 3

3

ブライアンのgroup_concat方法は、重複の数が少ない場合は機能しますが、そうでない場合は黙って失敗します。君が知ることはないだろう; 存在するはずの行が欠落するだけです。

少なくとも 1 つの説明が一致する (および重複が存在する) UPC をすべて選択し、そのリストから、それらの各 UPC に一致するすべての行を選択します。

すべてのアイテムを UPC でグループ化すると、それぞれにカウントで注釈を付けて、説明のいずれかが一致したかどうかにフラグを付けることができます。

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

(これは、 のようなブール演算子がLIKE実際0に false と1true を返すという事実を利用しています。その列の最大値を取得すると、行が一致したかどうかがわかります)

次に、条件に基づいてそのリストをフィルタリングして、関心のある UPC だけを取得できます。

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

そのリストを取得したら、それらの UPC のいずれかに一致するすべての製品を表示する必要があります。単純な(OUTERではない)結合でそれを行うことができます:

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)
于 2012-09-19T23:04:02.470 に答える
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');
于 2012-09-19T22:22:25.617 に答える
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を返すだけで済みます。

于 2012-09-19T22:17:35.720 に答える