1

私は、ダイナーとそのお気に入りのフレーバーとデザートを追跡する簡単なアプリケーションを持っています。recordsテーブルは単なるダイナーの名前とIDであり、テーブルmidはデザートとフレーバーを追跡します(ここでも、別の値のテーブルにリンクされたIDによって)。

CREATE TABLE IF NOT EXISTS `records` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;


INSERT INTO `records` (`id`, `name`) VALUES
(1, 'Jimmy Jones'),
(2, 'William Henry');


CREATE TABLE IF NOT EXISTS `mid` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `diner` int(11) NOT NULL,
  `dessert` int(11) NOT NULL DEFAULT '0',
  `flavor` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=11 ;


INSERT INTO `mid` (`id`, `diner`, `dessert`, `flavor`) VALUES
(1, 1, 3, 0),
(2, 1, 2, 0),
(3, 1, 15, 0),
(4, 1, 0, 1),
(5, 2, 3, 0),
(6, 2, 6, 0),
(7, 2, 0, 4),
(8, 1, 34, 0),
(9, 2, 0, 4),
(10, 2, 0, 22);

単純なクエリである必要があることに少し困惑していrecordsます。特定のデザートまたはフレーバーの要件が満たされているテーブルからすべてのIDを取得したいと思います。

SELECT a.id 
FROM records AS a
JOIN mid AS b ON a.id = b.diner
WHERE b.dessert IN (3,2,6)
AND b.flavor IN (4,22)

where句に一致するレコードがある場合でも、このクエリは行を返しません。明らかな何かが欠けていることは間違いありませJOINんが、INNER、OUTER、LEFT、RIGHTを試しましたが成功しませんでした。

誰かが私を正しい軌道に乗せて、私が欠けているものを説明できますか?

ありがとう

4

4 に答える 4

0

両方のwhere条件に一致するレコードはありません。

( 1, 1,  3,  0) - Matches dessert IN (3,2,6)
( 2, 1,  2,  0) - Matches dessert IN (3,2,6)
( 3, 1, 15,  0)
( 4, 1,  0,  1)
( 5, 2,  3,  0) - Matches dessert IN (3,2,6)
( 6, 2,  6,  0) - Matches dessert IN (3,2,6)
( 7, 2,  0,  4) - Matches flavor IN (4,22)
( 8, 1, 34,  0)
( 9, 2,  0,  4) - Matches flavor IN (4,22)
(10, 2,  0, 22) - Matches flavor IN (4,22)

おそらくあなたはORを意味しましたか?

SELECT a.id 
FROM records AS a
JOIN mid AS b ON a.id = b.diner
WHERE b.dessert IN (3,2,6)
OR b.flavor IN (4,22)

7つの結果を返す必要があります。

また、JOINについてのあなたの考えは赤いニシンです。LEFTとRIGHTの違いは、join句がそれらの間のレコードと一致しない場合にどちらのテーブルが優先されるかということです。INNERとOUTERの違いは、2つのテーブル間に一致するレコードがない場合に発生することです。結合の詳細については、コーディングホラーのこの説明記事を試してください(別のSOの質問で私に指摘してくれました)。

于 2013-01-17T22:19:58.450 に答える
0

WHERE条件は、「mid」テーブルのどのレコードにも適合しません。

(3、2、6)にデザートがあり、(4、22)にフレーバーがあるレコードがないため、クエリは(正しく)結果を返しません。

于 2013-01-17T22:19:12.327 に答える
0

組み合わせのあるダイナーが欲しいようです。1 つの方法を次に示します。

select diner
from records
group by diner
having max(b.dessert = 3) = 1 and
       max(b.dessert = 2) = 1 and
       max(b.dessert = 6) = 1 and
       max(b.flavor = 4) = 1 and
       max(b.flavor = 22) = 1

これはあなたのコメントに答えます:

select diner
from records
group by diner
having max(case when b.dessert in (2, 3, 6) then 1 esle 0 end) = 1 and
       max(case when b.dessert in (4, 22) then 1 else 0 end) = 1

条件に一致する 内のレコードを探しているだけの場合は、次を使用します。

select r.*, d.name
from records r join
     diner d
     on r.diner = d.id
where b.dessert IN (3,2,6) AND b.flavor IN (4,22)

これが必要な場合は、クエリの結合条件が間違っています (a.id は a.diner である必要があります)。

于 2013-01-17T22:18:27.427 に答える
0

SQLステートメントは問題ありませんが、サンプルレコードが条件を満たしていません。一致するレコードは次のようになります

dessert  flavor
3        4
3        22
2        4
2        33
6        4
6        22

入力レコードには、これらの組み合わせのいずれもありません

于 2013-01-17T22:18:00.377 に答える