我有这个样本表:
CREATE TABLE `dummy` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`userId` int(11) NOT NULL,
`pet` varchar(50) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=7 ;
INSERT INTO `dummy` (`id`, `userId`, `pet`) VALUES(1, 1, 'dog');
INSERT INTO `dummy` (`id`, `userId`, `pet`) VALUES(2, 1, 'cat');
INSERT INTO `dummy` (`id`, `userId`, `pet`) VALUES(3, 2, 'dog');
INSERT INTO `dummy` (`id`, `userId`, `pet`) VALUES(4, 2, 'cat');
INSERT INTO `dummy` (`id`, `userId`, `pet`) VALUES(5, 3, 'cat');
INSERT INTO `dummy` (`id`, `userId`, `pet`) VALUES(6, 4, 'dog');
如何在mysql中编写以下语句:
编辑:在dbemerlin的帮助下,我有前两个语句的解决方案。他们在这里:
检索拥有狗和猫的所有用户:
SELECT * FROM dummy WHERE pet = 'cat' OR pet = 'dog' GROUP BY userId HAVING COUNT(*) = 2
检索拥有狗或猫的所有用户:
SELECT * FROM dummy WHERE pet = 'cat' OR pet = 'dog' GROUP BY userId
我找到了解决方案3:
检索仅拥有猫的所有用户:
SELECT * FROM dummy WHERE userId IN (SELECT userId FROM dummy WHERE pet = 'cat' GROUP BY userId) GROUP BY userId HAVING COUNT(*) = 1
但阿德里亚诺有更好的解决方案:
SELECT * FROM dummy WHERE pet = 'cat' AND userId NOT IN (SELECT userId FROM dummy WHERE pet != 'cat');
但最后一句话仍有问题:
检索所有没有猫的用户:
SELECT * FROM dummy WHERE pet != 'cat' GROUP BY userId
这也不起作用。我真正需要的是检索所有没有猫但可能有其他宠物的用户。
谢谢!
编辑:这不是家庭作业。我试图在这里简化问题并解决问题。真实的情况是我正在尝试检索点击2个不同链接(存储为url字符串)等的用户。如果这是一个家庭作业,那么在这里询问如何实现这一点有什么不对?如果我有一个拥有MySQL知识的朋友,请问他告诉我解决方案并解释而不是问这里有什么不同?
答案 0 :(得分:1)
SELECT u.user_id
FROM user u
INNER JOIN dummy d
USING (user_id)
WHERE d.pet = 'cat'
OR d.pet = 'dog'
GROUP BY user_id
HAVING COUNT(*) = 2
SELECT u.user_id
FROM user u
INNER JOIN dummy d
USING (user_id)
WHERE d.pet = 'cat'
OR d.pet = 'dog'
GROUP BY user_id
SELECT u.user_id
FROM user u
INNER JOIN dummy d
USING (user_id)
WHERE d.pet = 'cat'
SELECT u.user_id
FROM user u
INNER JOIN dummy d
USING (user_id)
WHERE d.pet = 'dog'
答案 1 :(得分:1)
解决后一问题的一个方法是:
SELECT *
FROM dummy
WHERE pet = 'cat'
AND userId NOT IN (
SELECT userId
FROM dummy
WHERE pet != 'cat'
);
仅限有猫的用户。
这使您可以使用单个变量来表示您想要选择的宠物类型。
此处的结果,以及您发布的数据:
mysql> select * from dummy where pet = 'cat' and userId not in \
-> (select userId from dummy where pet != 'cat');
+----+--------+-----+
| id | userId | pet |
+----+--------+-----+
| 5 | 3 | cat |
+----+--------+-----+
1 row in set (0.00 sec)
编辑:
对于您的上一个问题,您只需撤消选择中的=
和!=
即可。在询问之前,请尝试考虑一下。
编辑: 你想知道性能。 MySQL提供的一个工具是EXPLAIN。使用关键字EXPLAIN对查询进行前缀将分析其性能,可能的执行路径,涉及的密钥和索引等。在这种情况下:
mysql> explain select * from dummy where pet = 'cat' and userId not in (select userId from dummy where pet != 'cat');
+----+--------------------+-------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+-------+------+---------------+------+---------+------+------+-------------+
| 1 | PRIMARY | dummy | ALL | NULL | NULL | NULL | NULL | 6 | Using where |
| 2 | DEPENDENT SUBQUERY | dummy | ALL | NULL | NULL | NULL | NULL | 6 | Using where |
+----+--------------------+-------+------+---------------+------+---------+------+------+-------------+
2 rows in set (0.00 sec)
mysql> explain SELECT * FROM dummy WHERE userId IN (SELECT userId FROM dummy WHERE pet = 'cat' GROUP BY userId) GROUP BY userId HAVING COUNT(*) = 1;
+----+--------------------+-------+------+---------------+------+---------+------+------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+-------+------+---------------+------+---------+------+------+----------------------------------------------+
| 1 | PRIMARY | dummy | ALL | NULL | NULL | NULL | NULL | 6 | Using where; Using temporary; Using filesort |
| 2 | DEPENDENT SUBQUERY | dummy | ALL | NULL | NULL | NULL | NULL | 6 | Using where; Using temporary; Using filesort |
+----+--------------------+-------+------+---------------+------+---------+------+------+----------------------------------------------+
2 rows in set (0.00 sec)
您会注意到您的查询在“额外”列中添加了“使用临时,使用filesort”。简而言之,这意味着效率较低,因为必须创建临时表,并且必须进行排序才能计算结果。您可以阅读this manpage了解更多信息。
答案 2 :(得分:1)
SELECT * FROM `dummy`
WHERE `pet` IN ('dog', 'cat')
GROUP BY `userId`
HAVING COUNT(DISTINCT `pet`) == 2
获取唯一身份用户列表
谁有狗或猫
但将其限制为至少有2个不同值pet
的用户
这将是一只狗和一只猫,因为你将它限制在那两个选项
答案 3 :(得分:0)
第一个问题有几种解决方案,“至少有一只狗和一只猫的用户。”
select * from dummy where userId in (select userId from dummy where pet = 'dog') and userId in (select userId from dummy where pet = 'cat');
使用相关子查询:
select * from dummy where exists (select 1 from dummy p where p.userId = d.userId and pet = 'dog') and exists (select 1 from dummy p where p.userId = d.userId and pet = 'cat')
性能取决于优化器。它们可能都有相同的执行计划。
select d.* from dummy d join (select distinct userId, pet from dummy where pet = 'dog') as g using (userId) join (select distinct userId, pet from dummy where pet = 'cat') as c using (userId);
最后一个使用Oracle称之为“内联视图”的内容。其他数据库供应商有不同的名称。如果这些查询在mySql中不起作用,请告诉我。