根据通过另一个表的“循环”计算SQL列

时间:2019-06-11 16:11:50

标签: sql sql-server

我想在我的实验室标本查询中添加一列,该列将遍历另一个表的所有可能行,然后计算INHOUSE,EXTERNAL或MULTISITE的状态。 需要查看另一个表,该表列出了第一个表的每一行中的多行。

  • 如果第二个表中所有TestSite实例均为“ XX”。然后列应显示INHOUSE
  • 如果第二个表中没有TestSite实例为“ XX”。然后列应显示EXTERNAL
  • 如果第二张表中的某些TestSite实例为“ XX”。然后列应显示MULTISITE

在SQL编码方面相对较新,有人可以建议我如何从第二张表计算相关值吗?会在第二张表中循环吗?

我尝试过执行表联接和CASE语句,但每个标本只能获得多行,而每个标本只能获得1行。

SELECT 
       SpecimenID
  FROM [LabSpecimens] LS  --this is the base table

SELECT 
      ,[SpecimenID]
      ,[TestSite]
  FROM [LabSpecimenTests]  --this is the table I want to calculate the extra column from

第二张表可能看起来像这样:

SpecimenID
----------
1
2
3
4


SpecimenID   TestSite
----------   --------
1            XX
2            YY
2            ZZ
3            YY
3            YY
3            XX
4            YY
4            ZZ
4            XX

预期结果应如下:

SpecimenID    Status
----------    ---------
1             INHOUSE
2             EXTERNAL
3             INHOUSE
4             MULTISITE

任何想法/协助将不胜感激。

3 个答案:

答案 0 :(得分:0)

您可以尝试使用条件聚合,并使用case来分析结果

select SpecimenID, case when t.count = t.XX then  'INHOUSE'
                        when t.XX = 0 then 'EXTERNAL' 
                        ELSE 'MULTISITE' 
                  end  
from (
    select SpecimenID
        , count(*) count 
        , sum( case when testSite = 'XX' then 1 else 0 end ) XX
    from  table2  
    group by SpecimenID
) t

答案 1 :(得分:0)

检查以下脚本。根据您的逻辑,应该给3加上“ EXTERNAL”标签,但您提到了“ INHOUSE”

SELECT T1.SpecimenID, 
CASE 
    WHEN MAX(TestSite) = 'XX' AND MIN(TestSite)  = 'XX'  THEN 'INHOUSE'
    WHEN MIN(TestSite) = 'XX' AND MAX(TestSite)  <> 'XX' THEN 'MULTISITE'
    ELSE 'EXTERNAL'
END
FROM Tab1 T1
INNER JOIN Tab2 T2 ON T1.SpecimenID = T2.SpecimenID
GROUP BY T1.SpecimenID

输出将如下所示-

SpecimenID Status
1          INHOUSE
2          EXTERNAL
3          EXTERNAL
4          MULTISITE

检查小提琴输出Here

答案 2 :(得分:0)

首先,我认为您不需要JOIN这两个表。

第二,假设值实际上是任意的,我不想依赖于字符串的顺序。所以,我建议:

SELECT T2.SpecimenID, 
       (CASE WHEN MAX(TestSite) = MIN(T2.TestSite) AND MIN(T2.TestSite)  = 'XX'
             THEN 'INHOUSE'   -- All XX
             WHEN SUM(CASE WHEN T2.TestSite = 'XX' THEN 1 ELSE 0 END) > 0
             THEN 'MULTISITE' -- Some XX
             ELSE 'EXTERNAL'
        END)
FROM Tab2 T2
GROUP BY T2.SpecimenID;

或者,不进行汇总,您可以执行以下操作:

select t1.*,
       (case when not exists (select 1  -- no record that is not an XX
                              from table2 t2
                              where t2.specimenid = t1.specimenid and
                                    t2.testsite <> 'XX'
                             )
             then 'INHOUSE'
             when exists (select 1       -- Some record that is an XX
                          from table2 t2
                          where t2.specimenid = t1.specimenid and
                                t2.testsite = 'XX'
                         )
             then 'MULTISITE'
             ELSE 'EXTERNAL'
       END)
from table1 t1;

因为这避免了聚合,所以使用tables(specimenid, testsite)上的索引可能会更快。