在JOIN时对同一张表进行多次交集运算
也许我遗漏了什么,我知道SQL是集合理论的,但我就是想不出这点。
表 Account:
| id | zip_code_id |
表 Package:
| id | name |
表 Account Package:
| account_id | package_id |
表 Package Special:
| package_id | special_id |
表 Special:
| id | name | zip_code_id |
假设你有一个账户,按定义,该账户拥有一个 zip_code,并将拥有一些套餐。
我想知道哪些特价商品同时满足这两个条件。 也就是说,邮编要匹配,且该特价商品与该账户的某个套餐相关联。
我以为就像下面这样简单:
account
INNER JOIN special by_location_special
ON account.zip_code = by_location_special.zip_code
INNER JOIN account_package
ON account.id = account_package.account_id
INNER JOIN package_special
ON account_package.package_id = package_special.package_id
INNER JOIN special by_package_special
ON package_special.special_id = package_special.id
WHERE account.id = :account_id
然而,这似乎不对,因为我不想在 Special 表上出现单独的实例。
我想把对 zip_code 和 package_special 的筛选应用到同一个 Special 表的实例上。
有什么见解吗,看看我是不是在做错事,以实现“通过JOIN在同一张表上同时过滤两者”的目标?我之所以问,是因为我用我的数据得到的输出与我的预期不符,使我怀疑我的方法是否真的按我想的那样运作。
解决方案
这只是对已有答案的补充,原答案已经解释了你的错误。
这就是你应该如何理解查询并编写它:
你在寻找的特价商品是:
SELECT ... FROM specials
但你只想要那些与账户X 关联且邮编与该账户相同的特价商品:
WHERE EXISTS ( <a link to account X with the same zip code> )
完整的查询:
SELECT *
FROM special s
WHERE EXISTS
(
SELECT null
FROM account a
JOIN account_package ap ON ap.account_id = a.id
JOIN package_special ps ON ps.package_id = ap.package_id
WHERE ps.special_id = s.id
AND a.id = :account_id
AND a.zip_code = s.zip_code
);
你也可以用一个 IN 子句来替代 EXISTS:WHERE s.id IN (SELECT ps.special_id ...)。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。