【问题标题】:Select from multiple table, eliminating duplicates values从多个表中选择,消除重复值
【发布时间】:2019-07-18 23:41:49
【问题描述】:

我有这些表和值:

Person                 Account                
------------------     -----------------------              
ID | CREATED_BY        ID | TYPE | DATA                 
------------------     -----------------------              
1 |                    1  | T1   | USEFUL DATA                
2 |                    2  | T2   |                 
3 |                    3  | T3   |
4 |                    4  | T2   |



Person_account_link                                       
--------------------------                     
ID | PERSON_ID | ACCOUNT_ID                                   
--------------------------                     
1 |  1         |   1                                
2 |  1         |   2                                  
3 |  2         |   3                        
4 |  3         |   4

我想选择所有具有 T1 帐户类型的人并获取数据列,对于其他人,他们应该在结果中没有任何帐户信息。

(我注意到人 1 有两个帐户:account_id_1 和 account_id_2,但必须显示一行(如果存在则为 T1 类型的优先级,否则为 null)

结果应该是:

Table1             
----------------------------------------------------- 
PERSON_ID | ACCOUNT_ID | ACCOUNT_TYPE | ACCOUNT_DATA    
----------------------------------------------------- 
1         |  1         |    T1        |  USEFUL DATA       
2         |  NULL      |   NULL       |  NULL         
3         |  NULL      |   NULL       |  NULL         
4         |  NULL      |   NULL       |  NULL         

【问题讨论】:

  • 如果一个人有多个 T1 账户怎么办?
  • 我应该展示第一个(但这不应该发生)

标签: sql postgresql


【解决方案1】:

你可以做条件聚合:

SELECT p.id,
       MAX(CASE WHEN a.type = 'T1' THEN a.id END) AS ACCOUNT_ID,
       MAX(CASE WHEN a.type = 'T1' THEN 'T1' END) AS ACCOUNT_TYPE,
       MAX(CASE WHEN a.type = 'T1' THEN a.data END) AS ACCOUNT_DATA 
FROM person p LEFT JOIN
     Person_account_link pl
     ON p.id = pl.person_id LEFT JOIN
     account a
     ON pl.account_id = a.id
GROUP BY p.id;

【讨论】:

    【解决方案2】:

    您需要一个外连接,从 Person 开始,然后到其他两个表。我还将与group bymin 聚合以解决一个人拥有两个或多个T1 帐户的情况。在这种情况下,将获取其中一个数据(其中的min):

    select    p.id person_id,
              min(a.id) account_id,
              min(a.type) account_type,
              min(a.data) account_data
    from      Person p
    left join Person_account_link pa on p.id = pa.person_id
    left join Account a on pa.account_id = a.id and a.type = 'T1'
    group by  p.id
    

    【讨论】:

    【解决方案3】:

    在 Postgres 中,我喜欢使用 FILTER 关键字。此外,如果您只想要拥有帐户的人,则不需要Person 表。如果你想要所有人:

    SELECT p.id,
           MAX(a.id) FILTER (a.type = 'T1') as account_id,
           MAX(a.type) FILTER (a.type = 'T1') as account_type,
           MAX(a.data) FILTER (a.type = 'T1') as account_data
    FROM Person p LEFT JOIN
         Person_account_link pl
         ON pl.person_id = p.id LEFT JOIN
         account a
         ON pl.account_id = a.id
    GROUP BY p.id;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-17
      • 1970-01-01
      • 2021-01-11
      • 2013-07-16
      • 1970-01-01
      • 2017-01-04
      • 2020-01-30
      • 1970-01-01
      相关资源
      最近更新 更多