Можете ли вы иметь логику if-then-else в SQL? [дубликат]
этот вопрос уже есть ответ здесь:
Как мне выполнить IF ... THEN в SQL SELECT?
22 ответов
мне нужно сделать выбор данных из таблицы на основе какого-то приоритета, например:
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? Используйте какой-то CASE-оператор для псевдо-if? Есть ли союз или какая-то другая умная вещь?
Edit: я использую MS SQL.
спасибо!
7 ответов:
вы можете сделать следующий 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
оператор CASE является самым близким к оператору IF в SQL и поддерживается во всех версиях SQL Server:
SELECT CASE <variable> WHEN <value> THEN <returnvalue> WHEN <othervalue> THEN <returnthis> ELSE <returndefaultcase> END FROM <table>
вместо
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
пожалуйста, проверьте, помогает ли это:
select TOP 1 product, price from table1 where (project=1 OR Customer=2 OR company=3) AND price IS NOT NULL ORDER BY company
С 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;кроме того, вы можете объединить все это в один
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;
есть оператор case, но я думаю, что ниже более точно/эффективно/легче читать то, что вы хотите.
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
--аналогичный ответ, как и выше по большей части. Код включен в тест
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
Comments