在JOIN时对同一张表进行多次交集运算

编程语言 2026-07-10

也许我遗漏了什么,我知道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_codepackage_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 子句来替代 EXISTSWHERE s.id IN (SELECT ps.special_id ...)

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章