选择在另一个表中按存在筛选的表的所有行

时间:2015-01-12 10:13:18

标签: mysql sql select join

我有一个药物表,其中包含ID和名称。在其中一个页面上,我需要创建一个包含所有药物名称的下拉列表 - 尽管我不能简单地这样做:

SELECT id, name FROM drug;

在这种情况下,我只想要在 pharmacy_has_drug 表中存在PZN代码的药物。要做到这一点,我需要以某种方式"经历" drug_product 表。

结构:

enter image description here

  • drug_product.drug_id 提及 drug.id
  • pharmacy_has_drug.drug_PZN 保留参考 drug_product.PZN

在这种情况下如何获得过滤后的药物?

3 个答案:

答案 0 :(得分:1)

你可以这样做:

SELECT d.id, d.name
FROM drug d
INNER JOIN drug_product p ON d.id=p.drug_id
WHERE p.drug= 62732

或者如果您在pharmacy_has_drug表上需要一个条件:

SELECT d.id, d.name
FROM drug d
INNER JOIN drug_product p ON d.id=p.drug_id
INNER JOIN pharmacy_has_drug ph ON ph.drug_PZN=d.PZN
WHERE ph.pharmacy_id= 12

编辑: 如果不需要,只需删除where子句。 内联接就足够了。

SELECT d.id, d.name
FROM drug d
INNER JOIN drug_product p ON d.id=p.drug_id
INNER JOIN pharmacy_has_drug ph ON ph.drug_PZN=d.PZN

答案 1 :(得分:1)

当您想知道记录是否存在时,请使用EXISTS:

SELECT id, name 
FROM drug
WHERE EXISTS
(
  select *
  from drug_product dp 
  join pharmacy_has_drug phd on phd.drug_pzn = dp.pzn
  where dp.drug_id = drug.id
);

或IN子句:

SELECT id, name 
FROM drug
WHERE id IN
(
  select dp.drug_id
  from drug_product dp 
  join pharmacy_has_drug phd on phd.drug_pzn = dp.pzn
);

您甚至可以拆分单步:1。在pharmacy_has_drug中给我所有的PZN。 2.从drug_product给我所有匹配的药物ID。 3.选择匹配的药物。

select id, name from drug
where id in
(
  select drug_id from drug_product
  where pzn in
  (
    select drug_pzn from pharmacy_has_drug
  )
);

答案 2 :(得分:1)

使用此查询:

SELECT DISTINCT d.id, d.name
FROM drug d
  INNER JOIN drug_product p ON p.drug_id = d.id
  INNER JOIN pharmacy_has_drug ph ON ph.drug_PZN = p.PZN

它分析表drugs中的所有行。对于每一个,它检查表drug_product以查找匹配的行。如果找不到这样的行,则忽略表drugs中的行(因为INNER JOIN)。如果找到一个或多个匹配的行,那么对于每个行,它会检查表pharmacy_has_drug以查找与drug_productPZN匹配的行。同样,如果找不到匹配的行,则已经计算的部分结果将被丢弃,并从drugs前进到下一行。
如果在pharmacy_has_drug中找到匹配的行,则会将一行或多行附加到结果集中;当药物可以在许多药房中找到时,则会为每个组合计算一行但是,因为只有表drugs中的列出现在SELECT子句中,所以最终结果集将包含重复项。

DISTINCT子句中的SELECT关键字删除重复项并使查询运行得更快(因为DISTINCT优化使引擎在第一次匹配后停止搜索其他行)。