За последние 24 часа нас посетили 19314 программистов и 1896 роботов. Сейчас ищут 760 программистов ...

Задачка с сериями данных и несовпадающими датами

Тема в разделе "PHP и базы данных", создана пользователем artoodetoo, 22 ноя 2015.

  1. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.129
    Симпатии:
    1.249
    Адрес:
    там-сям
    Чтобы вы не скучали, предлагаю конкурс на самое элегантное решение.

    Есть таблица продаж в виде (товар, дата, количество). Нам надо выбрать записи по нескольким выбранным товарам. Не факт, что даты продаж у разных товаров совпадают.

    Нужно получить полный список дат в которые было движение хотябы одного из выбранных товара. То есть если один товар продавался 1го, 2го и 3го января, а другой 2го, 3го и 5го — имеем даты 1,2,3,5 января. Надо получить движение всех выбранных товаров в эти даты. Будем считать, что если у какого-то из товара нет записи за дату, это равносильно записи с количеством == 0.

    Подойдет любой формат выдачи, лишь бы инфа была полной.

    http://sqlfiddle.com/#!9/22024
     
  2. Deonis

    Deonis Старожил

    С нами с:
    15 фев 2013
    Сообщения:
    1.521
    Симпатии:
    504
    Может я не так понял, но вот такой вариант:
    Код (PHP):
    1. SELECT 
    2.     `prod_id`, GROUP_CONCAT(DISTINCT `sale_date` SEPARATOR ', ') AS `dates`
    3. FROM 
    4.     `sales` 
    5. WHERE `quantity` <> 0 GROUP BY `prod_id`
     
  3. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.129
    Симпатии:
    1.249
    Адрес:
    там-сям
    Незачёт.

    Вот, кстати, демка где запрос уже работает: http://init.us.to/zhao/
    По картинке может быть понятно какого рода инфа требуется. И почему хочется иметь данные даже за отсутствующие дни.
     
  4. alexforce2

    alexforce2 Активный пользователь

    С нами с:
    25 дек 2013
    Сообщения:
    71
    Симпатии:
    12
    В голову пришло только такое решение
    Код (PHP):
    1. SELECT s1.sale_date, s2.prod_id, s2.quantity
    2. FROM sales s1
    3. LEFT JOIN  (SELECT * FROM sales where prod_id=1) AS s2 ON s1.sale_date = s2.sale_date
    4. GROUP BY s1.sale_date
    5. ORDER BY s1.sale_date
    http://sqlfiddle.com/#!9/22024/60/0
     
  5. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.129
    Симпатии:
    1.249
    Адрес:
    там-сям
    Что означает результат этого запроса?

    Добавлено спустя 4 минуты 40 секунд:
    Кажется это операции по товару №1 за все дни, какие были в таблице продаж. (А нет, показалось! Первая запись просто мусор.)
    А мне не нужны продажи за…
    т.е. в случае если выбран один товар как у вас, это тупо его дни. В случае двух товаров это объединение дней двух товаров и т.д. А не просто весь календарь.

    Попробуйте сделать запрос по двум товарам, почувствуете всю красоту задачи )
     
  6. alexforce2

    alexforce2 Активный пользователь

    С нами с:
    25 дек 2013
    Сообщения:
    71
    Симпатии:
    12
    Да.
    Нет, там будут отображены все существующие в таблице дни, независимо от того, в какой день был продан товар
     
  7. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.129
    Симпатии:
    1.249
    Адрес:
    там-сям
    Нет. Первая строка имеет prod_id = null. Неизвестный товар.

    А я вам объяснял что там должно было быть, а не что там у вас. Там должны быть даты продаж выбранных товаров.
     
  8. alexforce2

    alexforce2 Активный пользователь

    С нами с:
    25 дек 2013
    Сообщения:
    71
    Симпатии:
    12
    Значит, если в выборке должна быть стата по нескольким товарам за один запрос(при строки с днями не должны повторяться), то таблица с данными будет расти горизонтально, а не вертикально?

    Вот для 2 товаров http://sqlfiddle.com/#!9/22024/74/0 (что-то не работает изменение имени столбца)
    там, где prod_id = null, ясно что в данной колонке будет только товар с определённым ИД
     
  9. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.129
    Симпатии:
    1.249
    Адрес:
    там-сям
    Я не понимаю вашу логику. Поэтому хз как она будет расти. Меня устроит любой формат, если он будет понятен.

    это кому ясно? опишите правила как это сделать ясным для машины, у неё нет интуиции.

    моя логика подсказывает, что если у нас по двум товарам есть 12 фактов продаж, то правильная выборка должна отобразить все 12, каким-то образом. у вас я вижу 6 чисел в колонке quantity.

    Добавлено спустя 10 минут 39 секунд:
    вау! кажется sqlfiddle перекосило.

    Добавлено спустя 14 минут 35 секунд:
    Я понял что вы хотели построить что-то вроде кросс-таблицы, где новые товары создают новые колонки. Но ошибка с датами по прежнему на месте. У вас выведутся просто все даты, а не даты интересующего нас подмножества.
     
  10. alexforce2

    alexforce2 Активный пользователь

    С нами с:
    25 дек 2013
    Сообщения:
    71
    Симпатии:
    12
    Да, этого хотел, мне не кажется данное решение элегантным, но другого не придумал. Вот вариант с датами
    Код (PHP):
    1. SELECT sales.sale_date, 
    2.   product1.prod_id as product_id_1, product1.quantity as quantity_product_id_1, 
    3.   product2.prod_id as product_id_2, product2.quantity as quantity_product_id_2
    4. FROM sales
    5.   LEFT JOIN (SELECT * FROM sales where prod_id=1) AS product1 ON sales.sale_date = product1.sale_date
    6.   LEFT JOIN (SELECT * FROM sales where prod_id=2) AS product2 ON sales.sale_date = product2.sale_date
    7. WHERE 
    8.   sales.sale_date IN (SELECT DISTINCT sale_date FROM sales WHERE prod_id in(1,2))
    9. GROUP BY sales.sale_date
    10. ORDER BY sales.sale_date
    http://sqlfiddle.com/#!9/22024/83/0
     
  11. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.129
    Симпатии:
    1.249
    Адрес:
    там-сям
    Да, это вариант. Спасибо!

    Добавлено спустя 6 минут 59 секунд:
    У меня сейчас примерно такой запрос в работе: http://sqlfiddle.com/#!9/22024/87
    Код (PHP):
    1. SELECT apd.*, IFNULL(s.quantity, 0) AS quantity
    2. FROM
    3.   (
    4.     SELECT ap.prod_id, ad.sale_date
    5.     FROM 
    6.       (SELECT DISTINCT prod_id   FROM sales WHERE prod_id IN(1,2)) AS ap,
    7.       (SELECT DISTINCT sale_date FROM sales WHERE prod_id IN(1,2)) AS ad
    8.   ) AS apd LEFT JOIN
    9.   sales AS s USING(sale_date, prod_id)
    10. ORDER BY prod_id ASC, sale_date ASC