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