1

このテーブル構造とサンプルデータを考えると(t3はクエリで使用しないでください。ここでは、t1とt2の関係を示しています)。

      t1                 t2                         t3
--------------   -----------------   --------------------------------
| id | value |   | t1key | t3key |   | id | value                   |
|  1 |  2008 |   |     3 |     1 |   |  1 | "New intel cpu in 2010" |
|  2 |  2009 |   |     4 |     1 |   |  2 | "New amd cpu in 2008"   |
|  3 |  2010 |   |     6 |     1 |   |    |                     ... |
|  4 | intel |   |     1 |     2 |   --------------------------------
|  5 |   amd |   |     5 |     2 |
|  6 |   cpu |   |     6 |     2 |
|    |   ... |   |       |   ... |
--------------   -----------------

次の条件を満たすSQLクエリをどのように作成しますか。

Given the input for t1.id is the set {6} returns t1.id set {3,4,6,1,5}
Given the input for t1.id is the set {6,4} returns t1.id set {3,4,6}
Given the input for t1.id is the set {5,4} returns t1.id set {}

テーブルが大きくてもパフォーマンスが低下しません...?

4

5 に答える 5

2

これが私の素晴らしい貢献です(少なくとも今のところ素晴らしいと仮定しましょう:)

SELECT DISTINCT a2.t1key, COUNT( * ) AS cnt
FROM t2 AS a1
    LEFT JOIN t2 AS a2 ON a2.t3key = a1.t3key
WHERE a1.t1key IN ( 6, 4 ) 
GROUP BY a2.t3key, a2.t1key
HAVING cnt >=2

そのIN (6,4)部分は本当に自明です。2には、句の-scnt >=2の数があります。例:を使用している場合は、を使用する必要があります。idININ (6)cnt >=1

まったく必要かどうか>はわかりませんが、テストするためのより大きなデータセットを作成しないのは怠惰です:)

于 2011-03-30T09:27:01.170 に答える
1

あなたが何を望んでいるのかはあまり明確ではありません。

テーブルt1wordを呼び出し、テーブルt3phraseを呼び出し、テーブルt2を呼び出しますword is in phrase

次に、特定のword.idsのセットと同じフレーズにあるすべてのword.idsを検索したいと思います。あれは正しいですか?

SELECT DISTINCT t1.id
FROM t1 
  JOIN t2
    ON t1.id = t2.t1key
  JOIN t2 copyt2
    ON copyt2.t3key = t2.t3key 
WHERE copyt2.t1key IN
  (6,4)       --what you want to check here

修正

ジョーのコメントを読み、質問の詳細を読み直すと、指定したリスト内のすべての単語と同じフレーズに表示されるすべての単語を検索したいと思います。

これは、関係除算の問題のように見えます。

SELECT DISTINCT t2a.t1key
FROM t2 AS t2a
WHERE NOT EXISTS
  ( SELECT *
    FROM t2 AS t2b
    WHERE t2b.t1key IN (6,4)
      AND NOT EXISTS
      ( SELECT *
        FROM t2 AS t2c
        WHERE t2a.t3key = t2c.t3key
          AND t2c.t1key = t2b.t1key
      )
  )

2番目の解決策:

SELECT a.t1key
FROM t2 AS a
  JOIN t2 as b
    ON  a.t3key = b.t3key
WHERE b.t1key IN (6,4)       --list you want to check
GROUP BY a.t1key, a.t3key
HAVING COUNT(*) = 2          --size of list
;

3番目の解決策:

SELECT DISTINCT t1key
FROM t2
WHERE t3key IN
  ( SELECT t3key
    FROM t2
    WHERE t1key IN (6,4)
    GROUP BY t3key
    HAVING COUNT(*) = 2
  )
;

注:最初の(with NON EXISTS)ソリューションは、他の2つのソリューションとは大きな違いがあります。

そのメンバーがテーブルt2に表示されないリストで試してみると、たとえば(2)、または(2,7)、t2からのすべてのt1keyが表示されます。

このような場合、2番目と3番目のソリューションではキーがまったく表示されません。

于 2011-03-30T06:52:52.807 に答える
1
select distinct t1key
from t2
where t3key in
(
    select t3key from t2 where t1key = 6
    intersect
    select t3key from t2 where t1key = 4
)

==> 3, 4, 6

入力セットに含まれるアイテムの数に応じて、「intersect」句をさらに追加する必要があります。

SQLServerでテスト済み。

于 2011-03-30T06:52:59.277 に答える
1
select distinct t2b.t1key
from 
  t2 t2a
  inner join t2 t2b on t2a.t3key = t2b.t3key
where t2a.t1key in (6, 5) /* or whatever */

t1(キーワード)から始めて、「cpu」(またはその他)を含むすべてのt3(式)を取得します。t3に直接参加する必要はなく、そこからのデータも必要ありません。もう一度t2に参加すると、見つかった式に含まれている他のすべてのキーワードを取得します。それらのt1keyを返す必要があるだけです。


訂正:サブクエリが必要ない場合は、キーワードごとに結合を作成して、以下を検索できます。

select distinct t2b.t1key
from 
  t2 t2a
  inner join t2 t2b on t2a.t3key = t2b.t3key and t2a.t1key = 6
  inner join t2 t2c on t2a.t3key = t2c.t3key and t2a.t1key = 5
于 2011-03-30T06:53:14.407 に答える
0

彼はそこにいます、あなたは正しいテーブル構造を選んだのですか?正規化されていないようですが、各テーブルがどのエンティティを表すことができるかは正確にはわかりません。

データベース設計を少なくとも第3正規形に保つことが重要です(ウィキペディアの記事を参照)

あなたの質問ははるかに自然で簡単に定式化されます

于 2011-03-30T06:52:29.547 に答える