Где оператор Иерархия для выбора строк - PullRequest
0 голосов
/ 08 марта 2019

У меня есть таблица со столбцом с именем ReportTypeId.Я хочу выбрать строки, где ReportTypeId = 1, но если строк для этого не существует, то я хочу ReportTypeId = 2. Я пытаюсь использовать WHEN EXISTS, но я не могу понять, как выбрать более одного столбца.Я хочу написать запрос, который выглядит примерно так:

SELECT CASE 
    WHEN EXISTS (SELECT PerformanceReport FROM ReportData
                    WHERE (ReportId = 79 and ReportTypeId = 1))

        THEN (select * from ReferenceData               
                where ReportTypeId = 1)

        ELSE (select * from ReferenceData
                where ReportTypeId = 2)
    END

Но поскольку я пытаюсь вернуть более одного столбца, он не работает.Есть ли способ создать запрос, основанный на выражении WHERE, в зависимости от того, существуют данные или нет?

Ответы [ 3 ]

1 голос
/ 08 марта 2019

Если RecordTypeId можно заказать **, то вы можете использовать следующие

SELECT PerformanceReport 
FROM ReferenceData
WHERE ReportTypeId = (
      SELECT MIN(ReportTypeId) 
      FROM ReportData 
      WHERE ReportTypeId IN (1, 2)
        AND ReportId = 79
)

** по заказу, я имею в виду, что агрегатная функция MIN вернет ожидаемый результат.Однако для целых чисел это имеет смысл, если ваши идентификаторы типа отчета имеют текстовый uuids, тогда MIN все равно будет работать, но не даст ожидаемого результата, потому что он вернет минимальный идентификатор в лексическом порядке.

1 голос
/ 08 марта 2019

Вы, кажется, хотите:

SELECT refd.* 
FROM ReferenceData refd
WHERE (refd.ReportType = 1 AND 
       EXISTS (SELECT 1
               FROM ReportData repd
               WHERE repd.ReportId IN (1, 79)
              )
      ) OR
      (refd.ReportType = 2 AND 
       EXISTS (SELECT 1
               FROM ReportData repd
               WHERE repd.ReportId NOT IN (1, 79)
              )
      )
1 голос
/ 08 марта 2019

Вы можете использовать следующее решение:

SELECT * 
FROM ReferenceData
WHERE (
    ReportTypeId = 1 
    AND EXISTS (SELECT * FROM ReportData WHERE ReportTypeId = 1 AND ReportId = 79)
) OR (
    ReportTypeId = 2
    AND NOT EXISTS (SELECT * FROM ReportData WHERE ReportTypeId = 1 AND ReportId = 79)
)

Вы можете оптимизировать это с помощью JOIN:

SELECT ReferenceData.* 
FROM ReferenceData JOIN (
    SELECT EXISTS (SELECT * FROM ReportData WHERE ReportTypeId = 1 AND ReportId = 79) AS state
) isAvailable
WHERE (
    ReportTypeId = 1 AND isAvailable.state = 1
) OR (
    ReportTypeId = 2 AND isAvailable.state = 0
)

Вы можете добавить несколько чеков, используя JOIN:

SELECT ReferenceData.* 
FROM ReferenceData JOIN (
    SELECT EXISTS (SELECT * FROM ReportData WHERE ReportTypeId = 1 AND ReportId = 79) AS state
) avail1 JOIN (
    SELECT EXISTS (SELECT * FROM ReportData WHERE ReportTypeId = 2 AND ReportId = 79) AS state
) avail2 JOIN (
    SELECT EXISTS (SELECT * FROM ReportData WHERE ReportTypeId = 3 AND ReportId = 79) AS state
) avail3
WHERE (
    ReportTypeId = 1 AND avail1.state = 1
) OR (
    ReportTypeId = 2 AND avail1.state = 0 AND avail2.state = 1
) OR (
    ReportTypeId = 3 AND avail1.state = 0 AND avail2.state = 0 AND avail3.state = 1
) OR (
    ReportTypeId = 4 AND avail1.state = 0 AND avail2.state = 0 AND avail3.state = 0
)

демо на dbfiddle.uk

...