2016-10-08 13 views
0

は、私はパフォーマンスが向上しますより簡単に書き込むことができます推測するこのクエリを持っている:クエリのSQLこのクエリを簡略化してパフォーマンスを向上させる方法は?

SELECT COUNT(DISTINCT productid) 
FROM productwords pw 
WHERE productid IN 
(SELECT productid FROM productwords pw JOIN words w 
    ON pw.wordid = w.id WHERE word = 'nike') 
AND productid IN 
(SELECT productid FROM productwords pw JOIN words w 
    ON pw.wordid = w.id WHERE word = 'free') 

目標は言葉を持っている明確なproductidsの数=「ナイキ」と 'の両方を取得することです無料です。

ありがとうございます! on pw = w.idが実際に正しくない

SELECT COUNT(DISTINCT productid) 
FROM productwords pw 
    JOIN words w ON pw.productid = w.id 
WHERE word IN ('nike','free') 

あなたの現在のクエリ:私が正しくあなたの質問を理解していた場合

+0

いくつかのサンプルデータと望ましい結果を投稿してください。 –

+0

テーブル構造といくつかのサンプルデータを投稿してください。 – HorusKol

答えて

4

、これはちょうどjoinを使用して良いはずです。 joinをオンにしようとしているフィールドは、上記に含める必要があります。私はproductidを推測し、おそらくそのwordid代わりに...あなたは、単にこの

select count(*), w.word from product p left join words w on w.id = p.word_id where w.name = 'nike' or w.name = 'free' group by w.name 

希望のように、このクエリを実行して、クエリは、あなたの質問に答えることができ

+0

このクエリは、キーワードの* * *と一致する商品の数を返します。これはOPが意図したものかもしれませんが、仕様を少し違った形で読んでいます...カウントを返しますが、キーワード 'nike'とmatcheキーワード 'free'に一致する商品のみを*含む*。 (商品が「ナイキ」に合っていても「無料」と一致しない場合、その商品は含まれません) – spencer7593

+0

あなたは正しいです。返品される商品は両方のキーワードに一致する商品でなければなりません。無料 "です。 – Louisa

+0

"on pw = w.id"のエラーを修正しました。 "on pw.wordid = w.id"にする必要があります – Louisa

0

。また、あなたは多くの行を(の10,000 ++を言わせて)持っている場合は、productswords(製品剣の外部キー列という非常に奇妙なこの

SELECT count(*), w.name from product p JOIN (select id, name from words where name = 'nike' or name = 'free') w on w.id = p.word_id group by w.name 
+0

これは確かに幾分簡単なクエリです。しかし、これはまた、OPクエリの結果と大きく異なる*結果を返します。これは、各単語に関連する行の数を返します。これはOPが欲しいという結果かもしれませんが、私は仕様をかなり違って読んで、OPクエリと同等の結果を返します。 – spencer7593

+0

ああ、申し訳ありませんが、私はフィルターを挿入するのを忘れていました。私は私の答えを編集します。 –

0

のように改善することができ

where w.name in ('nike', 'free') 

でフィルタリングでき ?)テーブルの名前はpwで、word_idではありません。 (外字キーが実際に何か他の名前になっている場合は、以下のクエリのpw.pwpw.column_name ...と置き換えてください)

両方のキーワードに一致する商品を見つける2つの言葉は、 'nike'という単語に一致する商品のみを返し、 '無料'という単語に一致する場合のみ返します。

GROUP BYHAVINGという節を組み合わせて使用​​できます。 ..

カウントを取得するには、それを括弧で囲んで参照できますインラインビューとして...

SELECT COUNT(1) 
    FROM (SELECT pw.productid 
      FROM productwords pw 
      JOIN words w 
       ON w.id = pw.pw 
      AND w.word IN ('nike','free') -- keywords you are looking for 
      GROUP BY pw.productid 
      HAVING COUNT(DISTINCT w.word) = 2 -- number of keywords to match 
     ) v 

同等の結果を返す他のクエリパターンがあります。

SELECT pw.productid 
    FROM productwords pw 
    WHERE EXISTS (SELECT 1 
        FROM words w 
        WHERE w.id = pw.pw  -- related to row on outer query 
        AND w.word IN ('nike','free') 
       ) 
GROUP BY pw.productid 
HAVING COUNT(DISTINCT pw.pw) = 2 

、再び、単にカウントを取得括弧でそれをラップし、それを参照するには...指定された単語の両方に一致製品のみを取得するためにEXISTS (correlated subquery)パターンを使用して例えば

、インラインビューとして表示します。利用可能な

非自明なセットの場合

有する適切なインデックスは、が大幅両方のクエリのパフォーマンスを向上させることができます。例えば、

... ON productswords (pw, productid) 
    ... ON words (word, id) 
関連する問題