在PostgreSQL中处理子选择

时间:2018-07-19 06:22:57

标签: postgresql

在以下示例中,我们要查找具有不同ID的重复项

-- table msg
create table msg(
    id int primary key,
    msg varchar(10));

insert into msg
    values (1, 'single'),
           (2, 'twice'),
           (3, 'twice'),
           (4, 'threefold'),
           (5, 'threefold'),
           (6, 'threefold');

select * from msg;

计算具有不同ID的相同邮件的数量

第一个示例:

select id, msg, (select count(*) from msg m1 where m1.msg = msg) as cnt 
    from msg; 

=>错误的结果,因为子选择中的“ msg”被标识为“ m1.msg”,而不是“ msg.msg”

第二个示例:

select id, msg, (select count(*) from msg m1 where msg.msg = m1.msg) as cnt 
    from msg; 

=>正确的结果

第三个示例(可能更容易理解):

select m1.id, m1.msg, (select count(*) from msg m2 where m1.msg = m2.msg) as cnt 
    from msg m1;

=>正确的结果

问题: 第一个示例的行为是否符合SQL标准?

1 个答案:

答案 0 :(得分:0)

始终,我们应该使用表别名,并使用列名进行引用。否则,数据库将继续使用,因此我们将无法获得理想的结果。

引用表别名也可以解决一些性能问题。假设您已加入n个表,并在select子句和where子句中引用表列。当您执行查询时,系统将在解析过程中解析查询,它将检查各个表中的列可用性。如果您不使用别名,那么它必须检查所有表并找到具有该列的表。可能需要一些时间。为了避免这种情况,我们必须在相应的列中引用表别名。还要避免列模棱两可的定义错误

在子查询中,我们总是用表列引用表别名