假设我有以下数据库表:
╔═════════════════╦════════════╗
║ ADVERTISEMENTID ║ CATEGORYID ║
╠═════════════════╬════════════╣
║ 1 ║ A ║
║ 1 ║ C ║
║ 2 ║ A ║
║ 2 ║ B ║
║ 3 ║ A ║
╚═════════════════╩════════════╝
给定一个作为参数传递的类别列表,比如说 A, C
我只想找到那些只属于这两个类别的广告,在上面的例子中只有广告 1 会匹配。
任何人都可以帮我翻译成SQL吗?
答案 0 :(得分:2)
select advertismentid
from the_table
where categoryid in ('A', 'C')
group by advertismentid
having count(*) = 2;
SQLFiddle:http://sqlfiddle.com/#!12/b94d6/1
这假设同一个categoryid不能多次分配给同一个adsismentid。它还将包括具有A,C和其他类别的广告。
如果您想要那些完全类别A和C的广告,您需要排除那些具有超过该类别的广告:
select advertismentid
from the_table
where categoryid in ('A', 'C')
group by advertismentid
having count(*) = 2;
intersect
select advertismentid
from the_table
group by advertismentid
having count(*) = 2;
SQLFiddle:http://sqlfiddle.com/#!12/8901c/4
SQLFiddle还有另一个使用except
而不是intersect
如果您的DBMS受限且无法使用except
或intersect
,则可以使用此替代方法:
select t1.advertismentid
from the_table t1
where t1.categoryid in ('A', 'C')
group by t1.advertismentid
having count(*) = 2
and count(*) = (select count(*)
from the_table t2
where t2.advertismentid = t1.advertismentid)
答案 1 :(得分:1)
SELECT DISTINCT advertisementid
FROM tft t1
WHERE t1.categoryid IN ('A','C')
AND EXISTS (
SELECT * FROM tft t2
WHERE t2.advertisementid = t1.advertisementid
AND t2.categoryid IN ('A','C')
AND t2.categoryid <> t1.categoryid
);
答案 2 :(得分:1)
好像我来晚了,但无论如何这里是我的解决方案:
SELECT advertisement
FROM advertisement_childcare_types t1
LEFT JOIN (
SELECT childcare_types ct
FROM table_childcare_types tct
WHERE childcare_types IN (0, 1, 3)
) AS mytypes
ON t1.childcare_types = mytypes.ct
GROUP BY advertisement
HAVING SUM(IF(mytypes.ct IS NULL, -1, 1)) = 3;
您可以使用此修改版本在您的sqlfiddle中进行测试:
SELECT advertisement
FROM advertisement_childcare_types t1
LEFT JOIN (SELECT 0 as ct UNION SELECT 1 UNION SELECT 3) AS mytypes
ON t1.childcare_types = mytypes.ct
GROUP BY advertisement
HAVING SUM(IF(mytypes.ct IS NULL, -1, 1)) = 3;