Выбрать столбец со значением по умолчанию или столбец с пользовательским значением, если не ноль? - PullRequest
0 голосов
/ 13 сентября 2010

Я работаю над веб-приложением с набором данных, которые пользователи могут просматривать и редактировать.

Пользователи хотят настроить одно из полей, отображаемых для каждого элемента, например, «product_name».

Каждый продукт имеет набор значений по умолчанию в таблице, который одинаков для всех пользователей:

Таблица продуктов будет выглядеть следующим образом (пропуская синтаксис, вы поймете идею):

CREATE TABLE products (
  pid     int,            # product id
  pname   varchar         # product name (users want to customize this)
);

Мне нужно отображать настроенное имя продукта пользователя во всех таблицах / списках на моем сайте всякий раз, когда есть настроенное значение для этого продукта, но в противном случае отображается значение по умолчанию.

Для экономии места я подумал об использовании дополнительной таблицы, которая как бы «переопределяет» значения по умолчанию для любого данного пользователя, для любого данного продукта. Строки добавляются в эту таблицу по мере необходимости. У пользователя, который не настраивал имя продукта, не будет строк:

CREATE TABLE custom (
  pid     int,
  userid  int,
  pname   varchar
);

Я могу легко объединить эти две таблицы по идентификатору продукта и выбрать значение по умолчанию (products.pname) или пользовательское значение (custom.pname) для каждой строки в php, но я надеюсь, что есть больше эффективный способ сделать это в MySQL.

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

Не могли бы вы предложить другой способ справиться с этим?

Спасибо.

PS: может быть, тип JOIN, который позволил бы столбцу таблицы 2 с тем же именем переопределить столбец в таблице 1 для тех строк, где он существует в таблице 2?

Ответы [ 4 ]

2 голосов
/ 13 сентября 2010
select if(c.pname is not null, c.pname, p.pname) pname
  from products p left outer join custom c on c.pid = p.pid;

Левое внешнее соединение всегда обеспечивает совпадение строк, у которых будут нулевые поля, если соединение не удалось, вы можете проверить это с помощью функции if ().

2 голосов
/ 13 сентября 2010

Используйте комбинацию LEFT JOIN и COALESCE:

   SELECT p.pid,
          COALESCE(c.pname, p.pname) AS product_name
     FROM PRODUCT p
LEFT JOIN CUSTOM c ON c.pid = p.pid
                  AND c.userid = ?

Поскольку c.pname будет нулевым, если пользователь не предоставил пользовательское имя, функция COALESCE по умолчанию будет использовать следующее ненулевое значение - от p.pname.

1 голос
/ 13 сентября 2010

Вы ищете функцию COALESCE.

SELECT COALESCE(the_field, "This literal") FROM YOUR_TABLE

приводит к значению the_field, если the_field не равно NULL, в противном случае это «Этот литерал». Вы можете смешивать поля и литералы столько, сколько хотите ... так что SELECT COALESCE (this_field, that_field) тоже работает. Вы можете иметь более 2 параметров ... например ВЫБЕРИТЕ COALESCE (поле this, поле this, поле другое)

1 голос
/ 13 сентября 2010

Посмотрите на MySQL CASE -статмент .Это должно сработать:

   SELECT CASE
              WHEN `custom`.`pname` IS NULL
              THEN `products`.`pname`
              ELSE `custom`.`pname`
          END CASE AS `pname`
     FROM `products`
LEFT JOIN `custom`
       ON `custom`.`pid` = `products`.`pid`
    WHERE `products`.`pid` = 123

Я не проверял это, но вот как это должно работать в принципе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...