【问题标题】:SQL Join & CountSQL 连接和计数
【发布时间】:2015-10-04 20:27:11
【问题描述】:

我有两张表,一张是护理人员,另一张是 MS SQL Server 中的病人。每个病人都被分配了一些照顾者

╔════════════════╦══════════════════╦════════════════════╦═════════════════╗
║ Patient Name   ║  Primary Carer   ║  Secondary Carer   ║  Tertiary Carer ║
╠════════════════╬══════════════════╬════════════════════╬═════════════════╣
║ Joe Bloggs     ║  John Smith      ║  Oscar Wild        ║  Tom Cruise     ║
║ Mary Sue       ║  John Smith      ║  Matt Smith        ║  Peter Pan      ║
║ Peter Parker   ║  John Smith      ║  Oscar Wild        ║  Matt Smith     ║
╚════════════════╩══════════════════╩════════════════════╩═════════════════╝ 

我希望从我的护理人员表中选择所有记录,然后计算该护理人员在患者表中作为主要、二级或三级护理人员的次数,包括未分配给任何人的护理人员。

例如;

╔═══════════════╦═══════════════════════╦═════════════════════════╦═══════════════════╗
║ Carer         ║  Primary Carer Freq   ║  Secondary Carer Freq   ║  Third Carer Freq ║
╠═══════════════╬═══════════════════════╬═════════════════════════╬═══════════════════╣
║ John Smith    ║                   3   ║                     0   ║                 0 ║
║ Oscar Wilde   ║                   0   ║                     2   ║                 0 ║
║ Tom Cruise    ║                   0   ║                     0   ║                 1 ║
║ Matt Smith    ║                   0   ║                     1   ║                 0 ║
║ Peter Pan     ║                   0   ║                     0   ║                 1 ║
║ Barry White   ║                   0   ║                     0   ║                 0 ║
╚═══════════════╩═══════════════════════╩═════════════════════════╩═══════════════════╝ 

感谢您的帮助!

【问题讨论】:

    标签: sql-server select join count


    【解决方案1】:

    你可以使用:

    SqlFiddleDemo

    SELECT 
       [name]
      ,[Primary Carer Freq]   = COUNT(p1.[Primary Carer])
      ,[Secondary Carer Freq] = COUNT(p2.[Secondary Carer]) 
      ,[Third Carer Freq]     = COUNT(p3.[Tertiary Carer]) 
    FROM carers c 
    LEFT JOIN  patients p1
      ON p1.[Primary Carer] = c.[Name]
    LEFT JOIN  patients p2
      ON p2.[Secondary Carer] = c.[Name]
    LEFT JOIN  patients p3
      ON p3.[Tertiary Carer] = c.[Name]
    GROUP BY [name];
    

    数据:

    CREATE TABLE  patients([Patient Name] VARCHAR(100),
                           [Primary Carer] VARCHAR(100),
                           [Secondary Carer] VARCHAR(100),
                           [Tertiary Carer] VARCHAR(100) );
    
    
    INSERT INTO patients
    SELECT 'Joe Bloggs',      'John Smith',   'Oscar Wild',   'Tom Cruise' 
    UNION ALL SELECT 'Mary Sue',    'John Smith',     'Matt Smith',   'Peter Pan' 
    UNION ALL SELECT ' Peter Parker',   'John Smith',     'Oscar Wild',   'Matt Smith';
    
    CREATE TABLE carers(Name VARCHAR(100));
    
    INSERT INTO carers(Name)
    SELECT 'John Smith'   
    UNION ALL SELECT 'Oscar Wilde' 
    UNION ALL SELECT 'Tom Cruise' 
    UNION ALL SELECT 'Matt Smith'   
    UNION ALL SELECT 'Peter Pan'
    UNION ALL SELECT 'Barry White';
    

    编辑:

    如果您想要组合结果,请使用 +:

    SELECT 
      [name]
      ,[Primary&Secondary Carer Freq]   = COUNT(p1.[Primary Carer]) + COUNT(p2.[Secondary Carer]) 
      ,[Third Carer Freq]               = COUNT(p3.[Tertiary Carer]) 
    

    【讨论】:

    • select 中的子查询是效率最低的查询之一,select 中的每个子查询都会针对外部 select 返回的每一行执行。
    • @M.Ali 同意我准备带有三倍 LEFT JOIN 的版本。等一下
    • 如果先执行三遍GROUP BY,再执行三遍LEFT JOIN,可能会更有效。无论如何,+1,因为它返回正确的结果。
    • 当我尝试过时,这是将每个计数相乘,例如只包括主要的 10,那么如果我可以将主要和次要都更改为 20
    • 没关系,我现在解决了这个问题,我发现你的方法更容易实现,谢谢
    【解决方案2】:

    SQL Fiddle

    MS SQL Server 2008 架构设置

    CREATE TABLE Test_Table(PatientName VARCHAR(20), PrimaryCarer VARCHAR(20),
                           SecondaryCarer VARCHAR(20),TertiaryCarer VARCHAR(20));
    
    INSERT INTO  Test_Table VALUES                       
      ('Joe Bloggs'   ,     'John Smith'   ,      'Oscar Wild'     ,      'Tom Cruise'),      
      ('Mary Sue'     ,     'John Smith'   ,      'Matt Smith'     ,      'Peter Pan' ),      
      ('Peter Parker' ,     'John Smith'   ,      'Oscar Wild'     ,      'Matt Smith');
    

    查询 1

    SELECT CarerName
          ,COUNT(CASE WHEN  CarerType = 'PrimaryCarer'   THEN 1 END) AS PrimaryCarer
          ,COUNT(CASE WHEN  CarerType = 'SecondaryCarer' THEN 1 END) AS SecondaryCarer
          ,COUNT(CASE WHEN  CarerType = 'TertiaryCarer'  THEN 1 END) AS TertiaryCarer 
    FROM  Test_Table T 
     UNPIVOT (CarerName FOR CarerType  IN(PrimaryCarer,SecondaryCarer,TertiaryCarer)
             )up 
    GROUP BY CarerName
    

    Results

    |  CarerName | PrimaryCarer | SecondaryCarer | TertiaryCarer |
    |------------|--------------|----------------|---------------|
    | John Smith |            3 |              0 |             0 |
    | Matt Smith |            0 |              1 |             1 |
    | Oscar Wild |            0 |              2 |             0 |
    |  Peter Pan |            0 |              0 |             1 |
    | Tom Cruise |            0 |              0 |             1 |
    

    【讨论】:

    • 我想你错过了Barry White,即LEFT JOIN 与照顾者表。不过,+1,因为这种变体只扫描患者表一次,而不是 3 次。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多