您可以在 SQL 中使用 if-then-else 逻辑吗? [复制]
Posted
技术标签:
【中文标题】您可以在 SQL 中使用 if-then-else 逻辑吗? [复制]【英文标题】:Can you have if-then-else logic in SQL? [duplicate] 【发布时间】:2013-02-11 17:15:57 【问题描述】:我需要根据某种优先级从表中选择数据,如下所示:
select product, price from table1 where project = 1
-- pseudo: if no price found, do this:
select product, price from table1 where customer = 2
-- pseudo: if still no price found, do this:
select product, price from table1 where company = 3
也就是说,如果我发现 3 个产品的价格基于 project = X
,我不想在 customer = Y
上进行选择。我只想返回结果 3 行并完成。
你应该如何在 SQL 中做这样的事情?对伪 if 使用某种 CASE 语句?做一个工会或其他一些聪明的事情?
编辑:我正在使用 MS SQL。
谢谢!
【问题讨论】:
这会帮助你***.com/questions/5487892/… 您使用的是哪种 RDBMS,MS SQL Server、mysql、PostgreSQL...?对于它们中的每一个,控制流指令集都有些不同 您回答了自己的问题!用例语句! 从 SQL 中查看 CASE 语句 另见问题...***.com/questions/63447/… 【参考方案1】:--大多数情况下与上述类似的答案。包含用于测试的代码
DROP TABLE table1
GO
CREATE TABLE table1 (project int, customer int, company int, product int, price money)
GO
INSERT INTO table1 VALUES (1,0,50, 100, 40),(1,0,20, 200, 55),(1,10,30,300, 75),(2,10,30,300, 75)
GO
SELECT TOP 1 WITH TIES product
, price
, CASE WhereFound WHEN 1 THEN 'Project'
WHEN 2 THEN 'Customer'
WHEN 3 THEN 'Company'
ELSE 'No Match'
END AS Source
FROM
(
SELECT product, price, 1 as WhereFound FROM table1 where project = 11
UNION ALL
SELECT product, price, 2 FROM table1 where customer = 0
UNION ALL
SELECT product, price, 3 FROM table1 where company = 30
) AS tbl
ORDER BY WhereFound ASC
【讨论】:
【参考方案2】:CASE 语句最接近 SQL 中的 IF 语句,所有版本的 SQL Server 都支持:
SELECT CASE <variable>
WHEN <value> THEN <returnvalue>
WHEN <othervalue> THEN <returnthis>
ELSE <returndefaultcase>
END
FROM <table>
【讨论】:
这没有回答问题。 虽然 CASE 在所有版本的 MS SQL 上都很有用,但最近的版本确实具有 IF ELSE 功能。【参考方案3】:使用 SQL Server,您可以只使用 CTE 而不是 IF/THEN 逻辑,以便轻松映射现有查询并更改涉及的查询数量;
WITH cte AS (
SELECT product,price,1 a FROM table1 WHERE project=1 UNION ALL
SELECT product,price,2 a FROM table1 WHERE customer=2 UNION ALL
SELECT product,price,3 a FROM table1 WHERE company=3
)
SELECT TOP 1 WITH TIES product,price FROM cte ORDER BY a;
An SQLfiddle to test with.
或者,您可以将它们全部合并为一个 SELECT
以简化优化器;
SELECT TOP 1 WITH TIES product,price FROM table1
WHERE project=1 OR customer=2 OR company=3
ORDER BY CASE WHEN project=1 THEN 1
WHEN customer=2 THEN 2
WHEN company=3 THEN 3 END;
Another SQLfiddle.
【讨论】:
【参考方案4】:有一个案例陈述,但我认为以下内容更准确/更有效/更容易阅读您想要的内容。
select
product
,coalesce(t4.price,t2.price, t3.price) as price
from table1 t1
left join table1 t2 on t1.product = t2.product and t2.customer =2
left join table1 t3 on t1.product = t3.product and t3.company =3
left join table1 t4 on t1.product = t4.product and t4.project =1
【讨论】:
如果您在t1
中没有点击,则不会返回任何结果。
lol - t1, t2, t3 指向同一张桌子(如海报的要求) - 但我明白你的意思。相同的解决方案
sqlfiddle.com/#!6/b847b/3,适合测试。【参考方案5】:
请检查这是否有帮助:
select TOP 1
product,
price
from
table1
where
(project=1 OR Customer=2 OR company=3) AND
price IS NOT NULL
ORDER BY company
【讨论】:
这将返回匹配任何个条件的结果,没有任何优先顺序。【参考方案6】:可以进行如下sql查询
IF ((SELECT COUNT(*) FROM table1 WHERE project = 1) > 0)
SELECT product, price FROM table1 WHERE project = 1
ELSE IF ((SELECT COUNT(*) FROM table1 WHERE project = 2) > 0)
SELECT product, price FROM table1 WHERE project = 2
ELSE IF ((SELECT COUNT(*) FROM table1 WHERE project = 3) > 0)
SELECT product, price FROM table1 WHERE project = 3
【讨论】:
你如何在 codeigniter 查询构建器中做到这一点? ORA-00900: 句子 SQL 无效 @delive 这是 MS SQL,不是 Oracle。 那是无效的......所以不确定它是如何被投票 100 次的。 @Dalibor 您对答案有何担忧?它不适合你?【参考方案7】:不要使用EXISTS
和COUNT
,而是使用@@ROWCOUNT
:
select product, price from table1 where project = 1
IF @@ROWCOUNT = 0
BEGIN
select product, price from table1 where customer = 2
IF @@ROWCOUNT = 0
select product, price from table1 where company = 3
END
【讨论】:
+1 获得好的解决方案 这不是好的解决方案...不使用固有的数据库集功能。如果有多种不同的产品,我认为这也不正确。实际上 - 我认为最有知识的 dbs 会认为这是一个糟糕的解决方案。这正是我们试图教人们不要做的事情。 作为一名程序员并且不太喜欢 dbs,我认为这个解决方案看起来是最容易阅读和理解的 :) 但是,我得到了多个结果集,因为它执行了超过 1 个选择。有没有办法只返回 1 个结果集?另外,有人支持@mson 这是一个坏主意吗? 新问题:***.com/questions/15132192/… 这种语法很直观,适合快速而肮脏的解决方案。在 dbs 中它不是最优的,因为这种语法是程序性的 - 它比基于适当集合的查询慢几个数量级。以上是关于您可以在 SQL 中使用 if-then-else 逻辑吗? [复制]的主要内容,如果未能解决你的问题,请参考以下文章
如果表不存在,如何运行包含针对另一个 sql 实例上的表的查询的 If-Then-Else 语句?
可以在 Redshift 中完成 if-then-else 逻辑吗?