Where语句用于选择行的层次结构

问题描述 投票:0回答:3

我有一个名为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语句的查询?

sql select exists case-when
3个回答
1
投票

如果可以订购RecordTypeId **,那么您可以使用以下内容

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

**按顺序排列,我的意思是MIN聚合函数将返回预期的结果。对于整数,这是有道理的,但是,如果您的报告类型ID是文本uuids,那么MIN仍然可以工作但不会给您预期的结果,因为它将以词法顺序返回最小ID。


1
投票

您可以使用以下解决方案:

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
)

demo on dbfiddle.uk


1
投票

你似乎想要:

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)
              )
      )
© www.soinside.com 2019 - 2024. All rights reserved.