简体   繁体   English

如何使用内部连接查询防止重复(Postgres)

[英]how to prevent duplicates with inner join query (Postgres)

I am trying to understand how to create a query to filter out some results based on an inner join.我试图了解如何创建查询以根据内部联接过滤掉一些结果。

Consider the following data:考虑以下数据:

formulation_batch
-----
id  project_id  name    
1   1           F1.1
2   1           F1.2
3   1           F1.3
4   1           F1.all

formulation_batch_component
-----
id  formulation_batch_id    component_id
1   1                       1
2   2                       2
3   3                       3
4   4                       1
5   4                       2
6   4                       3
7   4                       4

I would like to select all formulation_batch records with a project_id of 1, and has a formulation_batch_component with a component_id of 1 or 2. So I run the following query:我想选择 project_id 为 1 的所有 Formation_batch 记录,并且有一个 Formation_batch_component 的 component_id 为 1 或 2。所以我运行以下查询:

SELECT formulation_batch.* 
FROM formulation_batch 
INNER JOIN formulation_batch_component
ON formulation_batch.id = formulation_batch_component.formulation_batch_id
WHERE formulation_batch.project_id = 1 
    AND ((formulation_batch_component.component_id = 2 
        OR formulation_batch_component.component_id = 1 ))

However, this returns a duplicate entry:但是,这会返回重复的条目:

1;"F1.1"
2;"F1.2"
4;"F1.all"
4;"F1.all"

Is there a way to modify this query so that I only get back the unique formulation_batch records which match the criteria?有没有办法修改此查询,以便我只取回符合条件的唯一配方批次记录?

EG:例如:

1;"F1.1"
2;"F1.2"
4;"F1.all"

Thanks for your time!感谢您的时间!

In this case it is possible to apply the distinct before the join possibly making it more performant:在这种情况下,可以在join之前应用distinct可能使其性能更高:

select fb.* 
from
    formulation_batch fb
    inner join
    (
        select distinct formulationbatch_id
        from formulation_batch_component
        where component_id in (1, 2)
    ) fbc on fb.id = fbc.formulationbatch_id 
where fb.project_id = 1

Notice how to use alias for the table names to make the query clearer.请注意如何为表名使用别名以使查询更清晰。 Also then in operator is very handy.然后in操作符中也很方便。 The use of double quotes with those identifiers is not necessary.不需要对这些标识符使用双引号。

One way would be to use distinct :一种方法是使用distinct

SELECT distinct "formulation_batch".* 
FROM "formulation_batch" 
INNER JOIN "formulation_batch_component" 
ON "formulation_batch"."id" = "formulation_batch_component"."formulationBatch_id" 
WHERE "formulation_batch"."project_id" = 1 
    AND (("formulation_batch_component"."component_id" = 2 
        OR "formulation_batch_component"."component_id" = 1 ))

I know the question asks how to prevent duplicates with inner join but could use an IN clause in the predicate.我知道这个问题询问如何使用内部连接防止重复,但可以在谓词中使用 IN 子句。

SELECT "formulation_batch".* 
FROM "formulation_batch" fb
ON "formulation_batch"."id" = "formulation_batch_component"."formulationBatch_id" 
WHERE "formulation_batch"."project_id" = 1 
 AND fb.id IN (SELECT "formulation_batch"."id"
               FROM formulation_batch_component
               WHERE (("formulation_batch_component"."component_id" = 2 
                      OR "formulation_batch_component"."component_id" = 1 ))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM