Рассчитать столбец SQL на основе «циклического прохождения» по другой таблице - PullRequest
1 голос
/ 11 июня 2019

Я хочу добавить в мой запрос лабораторных образцов столбец, который будет проходить по всем возможным строкам другой таблицы, а затем вычислять состояние INHOUSE, EXTERNAL или MULTISITE.Для этого нужно взглянуть на другую таблицу, в которой перечислены несколько строк для каждой строки из первой таблицы.

  • Если ВСЕ экземпляры TestSite во второй таблице равны 'XX'.тогда в столбце должно быть указано INHOUSE
  • Если ни один из экземпляров TestSite во второй таблице не равен «XX».тогда в столбце должно быть указано EXTERNAL
  • Если НЕКОТОРЫЕ экземпляры TestSite во второй таблице равны 'XX'.тогда в столбце должно быть написано MULTISITE

Будучи относительно новым в SQL-кодировании, кто-нибудь может посоветовать, как я могу вычислить соответствующее значение из 2-й таблицы?Будет ли это какой-то цикл через 2-ю таблицу?

Я пробовал делать объединения таблиц и операторы 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

Таблица 2 может выглядеть следующим образом:

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 голосов
/ 11 июня 2019

Проверьте этот скрипт ниже. Согласно вашей логике, 3 должен быть помечен как «ВНЕШНИЙ», но вы упомянули «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

Проверка выходных данных скрипты Здесь

0 голосов
/ 11 июня 2019

Во-первых, я не думаю, что вам нужно 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).

0 голосов
/ 11 июня 2019

Вы можете попробовать использовать условную агрегацию и проанализировать результат, используя регистр

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...