Как выполнить select?

340
17 мая 2017, 07:02
select category
     , sum(number*(1-abs(sign(region-1)))) as reg1
     , sum(number*(1-abs(sign(region-2)))) as reg2
     , sum(number*(1-abs(sign(region-3)))) as reg3
     , sum(number*(1-abs(sign(region-4)))) as reg4 
from groups 
    JOIN orders USING (id_order) 
WHERE datetime_order >= '$date_start' 
  AND datetime_order <= '$date_end' 
group by category;`

Этим кодом я получаю таблицу как на картинке. Всего может быть 8 категорий, то есть значение должны быть цифры от 1 до 8. Но в таблице не факт, что они все будут содержаться, особенно в этот промежуток времени. Как сделать, чтобы в первом столбце были цифры категорий, а в других соответствующие данные. Хочу, чтобы выводились нули, если по ним нем информации в таблице

Answer 1

Как правильно подметил Akina, используйте LEFT JOIN, который оставит все значения из таблицы groups. При left join в правой таблице orders при отсутствии пересекающихся значений будет null, поэтому, чтобы корректно использовать sum, необходимо добавить ifnull, coalesce или nvl на выбор:

select category
     , sum(ifnull(number*(1-abs(sign(region-1))), 0)) as reg1
     , sum(ifnull(number*(1-abs(sign(region-2))), 0)) as reg2
     , sum(ifnull(number*(1-abs(sign(region-3))), 0)) as reg3
     , sum(ifnull(number*(1-abs(sign(region-4))), 0)) as reg4 
from groups 
    LEFT JOIN orders ON groups.id_order = orders.id_order
         AND datetime_order between '$date_start' and '$date_end'
group by category
Answer 2
CREATE TEMPORARY TABLE temp1 (id int, reg1 int default 0, reg2 int default 0, reg3 int default 0, reg4 int default 0);
/* Заполнение */
INSERT INTO temp1 (id) VALUES ('1');
INSERT INTO temp1 (id) VALUES ('2');
INSERT INTO temp1 (id) VALUES ('3');
INSERT INTO temp1 (id) VALUES ('4');
INSERT INTO temp1 (id) VALUES ('5');
INSERT INTO temp1 (id) VALUES ('6');
INSERT INTO temp1 (id) VALUES ('7');
INSERT INTO temp1 (id) VALUES ('8');
INSERT INTO temp1 (id) VALUES ('9');
SELECT t.id, coalesce(subquery.reg1, t.reg1), coalesce(subquery.reg2, t.reg2), coalesce(subquery.reg3, t.reg3), coalesce(subquery.reg4, t.reg4)
FROM temp1 t
  LEFT JOIN
  (
    select category, sum(number*(1-abs(sign(region-1)))) as reg1,
                     sum(number*(1-abs(sign(region-2)))) as reg2,
                     sum(number*(1-abs(sign(region-3)))) as reg3,
                     sum(number*(1-abs(sign(region-4)))) as reg4
    from groups JOIN orders USING (id_order)
    WHERE datetime_order >= '$date_start' AND datetime_order <= '$date_end'
    group by category
  ) subquery ON t.id = subquery.category;
DROP TABLE temp1;

В итоге все хорошо работает через временную таблицу

READ ALSO
Android не подключается к СУБД MySQL через PHP

Android не подключается к СУБД MySQL через PHP

Выполняю работу по примеру, но почему то приложение не добавляет запись в БД, хотя если в php изменить переменные на текст, то запись при выполнении...

269
Массовая замена id на порядковые номера

Массовая замена id на порядковые номера

ЗдравствуйтеПоясню вопрос

356
SQLite join пустая таблица

SQLite join пустая таблица

Имеются таблицы:

324
MySQL запрос из четырех таблиц

MySQL запрос из четырех таблиц

Ребят помогите решить задачку, никак не складываеться в голове1) Напишите запрос, который выводит имена всех учеников, сдавших экзамен по математике...

445