CASE + IF MysQL-запрос - PullRequest
       32

CASE + IF MysQL-запрос

2 голосов
/ 16 июня 2010

Проблема заключается в следующем.У меня есть продукт, который может быть в одной из трех категорий (определяется category_id).Каждая таблица категорий имеет поле category_id, связанное с category_id в таблице продукта.Итак, у меня есть 3 случая.Я проверяю, есть ли мой product.category_id в таблице один.Если да, я беру некоторые значения.Если нет, я проверяю оставленные таблицы.Что я могу написать в разделе ELSE?Кто-нибудь может исправить мой запрос?

CASE
    WHEN IF EXISTS(SELECT * FROM table1 WHERE category_id='category_id') THEN SELECT type_id FROM table1 WHERE category_id='category_id';
    WHEN IF EXISTS(SELECT * FROM table2 WHERE category_id='category_id') THEN SELECT value_id FROM table2 WHERE category_id='category_id';
    WHEN IF EXISTS(SELECT * FROM table3 WHERE category_id='category_id') THEN SELECT group_id FROM table3 WHERE category_id='category_id';
ELSE "dont know what here";
END;

Ответы [ 6 ]

2 голосов
/ 16 июня 2010

В else вы бы поместили все, что хотите, в качестве значения по умолчанию, например, null.

Я думаю, что было бы гораздо эффективнее создать три левых объединения вместо нескольких подзапросов для каждого продукта в результате и использовать coalesce, чтобы получить первое существующее значение. Пример:

select coalesce(t1.type_id, t2.value_id, t3.group_id)
from product p
left join table1 t1 on t1.category_id = p.category_id
left join table2 t2 on t2.category_id = p.category_id
left join table3 t3 on t3.category_id = p.category_id
1 голос
/ 08 ноября 2012

пример

SELECT CompanyName, 
    Fax, 
    CASE WHEN IF(Fax='', 'No Fax', 'Got Fax')='No Fax' THEN NULL 
         ELSE IF(Fax='', 'No Fax', 'Got Fax') 
    END AS Note
FROM Customers;
0 голосов
/ 16 июня 2010

В дополнение к ответу Гуффы, здесь есть еще один подход - предполагая, что @category_id равен

SET @category_id = 'some_category_id_value'

, тогда

SELECT t1.type_id
WHERE category_id = @category_id
UNION ALL
SELECT t2.value_id
WHERE category_id = @category_id
UNION ALL
SELECT t3.group_id
WHERE category_id = @category_id

должен вернуть то, что вы просите (и производительность тоже неплохая).

Если у вас есть определенные category_id в более чем одной таблице, вы получите несколько записей (вы можете получить из этого, ограничив количество результатов до 1; вам может понадобиться сделать весь союзподзапрос и закажите его, но не уверен, обратитесь к документации)

Тем не менее, ваш вопрос выглядит так, как будто у вас есть проблемы с дизайном ваших таблиц

  • почему вы держите три категорииа не одна таблица?
  • Какова связь между type_id, value_id и group_id и почему имеет смысл выбирать их, как если бы они были одним и тем же (каково значение / семантика каждой таблицы / столбца)?
  • как вы гарантируете, что у вас нет записей в нескольких таблицах, которые соответствуют одному продукту (и реализуете другие бизнес-правила, которые у вас могут быть)?

Эти вопросы могут иметьправильные ответы, но вы должны знать их:)

0 голосов
/ 16 июня 2010

или что-то вроде этого

CASE
    WHEN IF EXISTS(SELECT * FROM table1 WHERE category_id='category_id') THEN SELECT type_id FROM table1 WHERE category_id='category_id';
    WHEN IF EXISTS(SELECT * FROM table2 WHERE category_id='category_id') THEN SELECT value_id FROM table2 WHERE category_id='category_id';
ELSE SELECT group_id FROM table3 WHERE category_id='category_id';
0 голосов
/ 16 июня 2010

Вам не нужно использовать ELSE, если больше нечего делать.

0 голосов
/ 16 июня 2010

Вы можете включить это ... ВЫБЕРИТЕ "Неизвестный тип" ИЗ таблицы1;

...