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

您的 SQL 语句很好,但您的示例记录不符合您的条件,匹配的记录应如下所示

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

您的输入记录中没有任何这些组合

于 2013-01-17T22:18:00.377 回答
0

你似乎想要有组合的食客。这是一种方法:

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

如果您只是在 a 中查找符合条件的记录,请使用:

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

您的 WHERE 条件不适合“中间”表中的任何记录。

没有记录在 (3, 2, 6) 中有甜点并且在 (4, 22) 中有风味,因此查询(正确)不返回任何结果。

于 2013-01-17T22:19:12.327 回答
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 之间的区别只是当连接子句与它们之间的记录不匹配时,哪个表具有优先权。INNER 和 OUTER 之间的区别只是当两个表之间没有匹配的记录时会发生什么。试试这篇来自编码恐怖的解释性文章,了解有关连接的更多详细信息(在另一个 SO 问题中向我指出,嘿嘿)。

于 2013-01-17T22:19:58.450 回答