MySQL: как использовать COALESCE - PullRequest
9 голосов
/ 10 апреля 2011

Скажем, у меня есть следующая таблица:

TABLE: product
===============================================================================
| product_id | language_id | name           | description                     |
===============================================================================
| 1          | 1           | Widget 1       | Really nice widget. Buy it now! |
-------------------------------------------------------------------------------
| 1          | 2           | Lorem  1       |                                 |
-------------------------------------------------------------------------------

Как мне запросить это так, что он пытается дать мне name и description, где language_id = 2, но вернуться кlanguage_id = 1, если столбец содержит NULL?

В приведенном выше примере я должен получить Lorem 1 для name и Really nice widget. Buy it now! для description.

Ответы [ 5 ]

8 голосов
/ 10 апреля 2011

Как насчет этого?

SET @pid := 1, @lid := 2;
SELECT 
    COALESCE(name,(
        SELECT name
        FROM product
        WHERE product_id = @pid AND description IS NOT NULL
        LIMIT 1
    )) name, 
    COALESCE(description,(
        SELECT description
        FROM product
        WHERE product_id = @pid AND description IS NOT NULL
        LIMIT 1
    )) description
FROM product
WHERE product_id = @pid 
    AND (language_id = @lid 
    OR language_id = 1)
ORDER BY language_id DESC
LIMIT 1;

где:

  • @pid: идентификатор текущего продукта
  • @lid: идентификатор текущего языка
  • Значения для name и / или description могут быть нулевыми
  • language_id = 2 элемент не может существовать
1 голос
/ 10 апреля 2011
select name, description from product
where product_id = @pid
  and name is not null
  and description is not null
  and (language_id = @lang or language_id = 1)
order by language_id desc

где @pid - идентификатор текущего продукта, а @lang - идентификатор текущего языка.

Первая возвращенная строка будет содержать текущее имя и описание.

Предполагается, что строка language_id = 1 НЕ будет содержать NULL в имени или описании.

0 голосов
/ 30 сентября 2013

Вот пример использования с SQL Update:

Это похоже на Oracle NVL. Вы можете использовать его, как показано ниже, в подготовленном выражении, используя параметры

UPDATE
    tbl_cccustomerinfo
SET
    customerAddress = COALESCE(?,customerAddress),
    customerName =  COALESCE(?,customerName),
    description =  COALESCE(?,description)
WHERE
    contactNumber=?
0 голосов
/ 02 февраля 2013

Предположение: есть запись для каждого продукта с языком = 1 Приведенный ниже код является простым SQL для получения того, что вы хотите.

Еще одна тема, если вы хотите, чтобы поведение, которое вы запрашивали ... потому что вы можете иметь смешанные языки между «имя» и «описание». Я бы разработал его по-другому, если бы одно из двух полей было пустым, я бы по умолчанию вернулся к основному языку (1).

select p.product_id
      ,coalesce(pl.name, p.name, 'No name') as name
      ,coalesce(pl.description, p.description, 'No description') as description
  from product p
  left join product pl on ( pl.product_id = p.product_id and pl.language_id = :language_id)
  )
 where p.product_id  = :product_id and p.language_id = 1
0 голосов
/ 10 апреля 2011
select p2.product_id
      ,coalesce(p2.name, p1.name, 'No name') as name
      ,coalesce(p2.description, p1.description, 'No description') as description
  from product p2
  left join product p1 on(
       p1.product_id = p2.product_id
   and p1.language_id = 1
  )
 where p2.product_id  = 1
   and p2.language_id = 2;

Edit1:
Приведенный выше запрос предполагает, что строка language = 2 существует, но имя / descr может быть нулевым.

Редактировать 2.
Я только что вспомнил, как кто-то недавно задавал похожий вопрос. А потом я обнаружил, что это был вы . Вы должны отделить продукты от переводов. Вот что затрудняет написание этого запроса. Томас ответ позволяет легко делать то, что вы хотите.

...