用于选择行的 Where 语句层次结构
Posted
技术标签:
【中文标题】用于选择行的 Where 语句层次结构【英文标题】:Where statement Hierarchy for Selecting rows 【发布时间】:2019-03-08 19:13:39 【问题描述】:我有一个表,其中包含一个名为 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 语句的查询?
【问题讨论】:
【参考方案1】:如果RecordTypeId
可以订购**,那么你可以使用以下
SELECT PerformanceReport
FROM ReferenceData
WHERE ReportTypeId = (
SELECT MIN(ReportTypeId)
FROM ReportData
WHERE ReportTypeId IN (1, 2)
AND ReportId = 79
)
** 按顺序,我的意思是 MIN
聚合函数将返回预期结果。但是,对于整数,这是有道理的,如果您的报告类型 id 是文本 uuid,那么 MIN
仍然可以工作,但不会给您预期的结果,因为它会按词法顺序返回最小 id。
【讨论】:
这对我的情况很有用,但我可以看到,如果 ReportTypeId = 2 成为优先于 1 的优先级,但不像 3 (2 > 1 > 3) 那样导入,那么我猜我运气不好?...好吧,我想我可以创建一个临时表来分配重要性等级,所以实际上是的,我真的很喜欢这个解决方案,谢谢! @Mwspencer 。 . .当这个答案似乎没有从正确的表格中选择时,我对如何接受这个答案感到困惑。 @GordonLinoff,我认为这不仅仅是我接受的硬代码的想法。由于我的实际用户案例比我的问题要复杂一些,因此这个答案有助于创建最直接的解决方案。我承认我没有测试过性能,因为这对我的具体情况并不重要。所有答案都给出了正确的输出,但这个用最少的代码。【参考方案2】:您可以使用以下解决方案:
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
【讨论】:
【参考方案3】:你似乎想要:
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)
)
)
【讨论】:
这似乎是一个干净的解决方案,但我不确定为什么使用 AND。如果 ReportTypeId = 1,我想选择报告,否则,我想要 ReportType = 2,但我不想要两种报告类型。我也不确定我们为什么要寻找 repd.ReportId IN (1, 79) 而不仅仅是 repd.ReportId = 79。 @Mwspencer 。 . .谢谢你。那是一个错字。以上是关于用于选择行的 Where 语句层次结构的主要内容,如果未能解决你的问题,请参考以下文章