代码之家  ›  专栏  ›  技术社区  ›  anjanb

Postgres SQL:如何在此SQL中进行分组

  •  0
  • anjanb  · 技术社区  · 14 年前

    下面的SQL从审计表family_Audit和family_address_Audit生成报告。

    (SELECT fam.familyserialno, fam.familyname, addr.housenumber, addr.address1,
            COALESCE(fam.operation, addr.operation) op,
            COALESCE(fam.username, addr.username) usr,
            COALESCE(fam.adddate, addr.adddate) add_date,
            (SELECT r.userrolename 
               FROM userrole_master r, user_master u 
              WHERE u.loginid=COALESCE(fam.username, addr.username) AND r.userrole_id=u.userrole_id) rolename
      FROM family_audit fam
           INNER JOIN family_address_audit addr USING(txid, family_id)
    WHERE (fam.node_id = 8) AND (fam.familyserialno >=1 and fam.familyserialno <=5)
    )
    UNION
    (SELECT fam.familyserialno, fam.familyname,
            addr.housenumber, addr.address1,
            COALESCE(fam.operation, addr.operation) op,
            COALESCE(fam.username, addr.username) usr,
            COALESCE(fam.adddate, addr.adddate) add_date,
            (SELECT r.userrolename 
               FROM userrole_master r, user_master u 
              WHERE u.loginid=COALESCE(fam.username, addr.username) AND r.userrole_id=u.userrole_id) rolename
       FROM family_audit fam
            FULL OUTER JOIN family_address_audit addr USING(txid, family_id)
      WHERE ((fam.familyserialno IS NULL and addr.family_id in 
                 (select family_id 
                    from family 
                   where familyserialno >=1 and familyserialno <=5 and node_id =8)) 
             OR ((addr.family_id IS NULL) and ((fam.familyserialno >=1 and fam.familyserialno <=5) and fam.node_id=8) ) )
    )
    ORDER BY add_date DESC;
    

    “above”SQL的典型输出如下

     familyserialno | familyname | housenumber |  address1  | op |  usr  |        add_date         | rolename
    ----------------+------------+-------------+------------+----+-------+-------------------------+----------
                  3 | thirda     |             |            | U  | admin | 2010-11-24 15:29:34.312 | admin
                    |            | 34324       | sdfdsfdsf  | U  | admin | 2010-11-24 15:28:42.314 | admin
                  3 | third      |             |            | I  | admin | 2010-11-24 15:28:34.576 | admin
                    |            | 333         | sdfdsf     | U  | admin | 2010-11-24 15:18:57.129 | admin
                  2 | aSecond    |             |            | I  | admin | 2010-11-24 14:58:15.477 | admin
                  1 | anjanFirst | anjanFirst  | anjanFirst | I  | admin | 2010-11-24 14:12:35.477 | admin
    

    ======================

    我想按fam.familyseriano对输出进行分组。因此,我修改了上面的SQL如下;但是,这会导致一个错误(在最后)

    SELECT * from 
    ((SELECT fam.familyserialno, fam.familyname, addr.housenumber, addr.address1,
            COALESCE(fam.operation, addr.operation) op,
            COALESCE(fam.username, addr.username) usr,
            COALESCE(fam.adddate, addr.adddate) add_date,
            (SELECT r.userrolename 
               FROM userrole_master r, user_master u 
              WHERE u.loginid=COALESCE(fam.username, addr.username) AND r.userrole_id=u.userrole_id) rolename
      FROM family_audit fam
           INNER JOIN family_address_audit addr USING(txid, family_id)
    WHERE (fam.node_id = 8) AND (fam.familyserialno >=1 and fam.familyserialno <=5)
    )
    UNION
    (SELECT fam.familyserialno, fam.familyname,
            addr.housenumber, addr.address1,
            COALESCE(fam.operation, addr.operation) op,
            COALESCE(fam.username, addr.username) usr,
            COALESCE(fam.adddate, addr.adddate) add_date,
            (SELECT r.userrolename 
               FROM userrole_master r, user_master u 
              WHERE u.loginid=COALESCE(fam.username, addr.username) AND r.userrole_id=u.userrole_id) rolename
       FROM family_audit fam
            FULL OUTER JOIN family_address_audit addr USING(txid, family_id)
      WHERE ((fam.familyserialno IS NULL and addr.family_id in 
                 (select family_id 
                    from family 
                   where familyserialno >=1 and familyserialno <=5 and node_id =8)) 
             OR ((addr.family_id IS NULL) and ((fam.familyserialno >=1 and fam.familyserialno <=5) and fam.node_id=8) ) )
    ))
    GROUP BY 1 
    ORDER BY 7 DESC;
    

    错误:中的子查询必须具有别名 第2行:((选择fam.familyserialno、fam.familyname、addr.houseNumber。。。 ^ 提示:例如,FROM(SELECT…[AS]foo。

    我该怎么解决?我们真的需要所有的行按fam.familyseriano分组。

    非常感谢你,

    附言:我们正在使用Postgres8.4.4。

    1 回复  |  直到 14 年前
        1
  •  4
  •   jmz    14 年前

    您需要对子查询进行别名,如下所示:

     SELECT * FROM ((SELECT ...) UNION (SELECT ...)) AS foo GROUP BY 1 ORDER BY 7 DESC;
    

    在这里 foo 是子查询的别名。