Можете ли вы иметь логику 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.



спасибо!

449   7  

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;

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.

есть оператор 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

    Ничего не найдено.