выберите продажи сгруппированного диапазона дат каждого месяца (SQLite) - PullRequest
1 голос
/ 11 ноября 2019

Мне нужно сделать запрос, получив месяцы, когда продажи не производились. (SQLITE)

Таблица

| id |    date    | total | id_user |
|  1 | 2019-01-01 | 400   |    1    |
|  2 | 2019-01-09 | 600   |    1    |
|  3 | 2019-08-01 | 100   |    1    |
|  4 | 2019-08-08 | 500   |    1    |
|  5 | 2019-08-15 | 1400  |    1    |
|  6 | 2019-09-01 | 7000  |    1    |

У меня есть этот запрос

SELECT 
    sum(venta.total) as Total,
    strftime('%m',venta.fecha_venta) as Month, 
    strftime('%Y',venta.fecha_venta) as Year
FROM venta 
LEFT JOIN VENTA_ESPECIE 
WHERE strftime('%Y', date('now')) == strftime('%Y',venta.fecha_venta) 
AND venta.fecha_venta 
BETWEEN '2019-01-30' AND '2019-10-30'
 GROUP by Month ;

Результат

| Total | Month | Year |
| 1000  |  01   | 2019 |
| 2000  |  08   | 2019 |
| 7000  |  09   | 2019 |

Я хочу получить этот результат

| Total | Month | Year |
| 1000  |  01   | 2019 |
|   0   |  02   | 2019 |
|   0   |  03   | 2019 |
|   0   |  04   | 2019 |
|   0   |  05   | 2019 |
|   0   |  06   | 2019 |
|   0   |  07   | 2019 |
| 2000  |  08   | 2019 |
| 7000  |  09   | 2019 |
|   0   |  10   | 2019 |

важно то, что между двумя датами может измениться

Ответы [ 2 ]

2 голосов
/ 11 ноября 2019

Следующее решение аналогично @ MikeT, но вычисляет минимальный и максимальный периоды времени. Кроме того, входная таблица была названа sales.

WITH monthly AS
       (SELECT strftime('%m', date) as Month, 
               strftime('%Y', date) as Year,
               total
        FROM sales),
     minmax AS
       (SELECT MIN(date) mn,
               MAX(date) mx
        FROM sales),
     cte_dates(dates) AS 
       (SELECT mn from minmax
        UNION ALL SELECT date(dates,'+1 Months')
                  FROM cte_dates WHERE dates <= (SELECT mx FROM minmax)),
     result AS
       (SELECT dates, total FROM cte_dates
        NATURAL LEFT JOIN
        (SELECT Year || '-' || Month || '-01' AS dates, SUM(total) total
         FROM monthly
         GROUP BY Year, Month))
SELECT COALESCE(total,0) as Total,
       strftime("%m", dates) as Month,
       strftime("%Y", dates) as Year
FROM result;
1 голос
/ 11 ноября 2019

Я считаю, что следующее будет делать то, что вы хотите: -

WITH cte_dates(dates) /*CTE generates a list of dates in the given range */ AS 
    (
        SELECT '2019-01-01' /*<<<< start of range */
        UNION ALL SELECT date(dates,'+1 Months') FROM cte_dates WHERE dates <= '2019-10-01' /*<<<< end of range */
    )

SELECT 
    coalesce(
        (
            SELECT sum(total) 
            FROM venta 
            WHERE strftime('%Y',date) = strftime('%Y',dates) 
                AND strftime('%m',date) = strftime('%m',dates)
        )
        ,0 /* 0 instead of null for coalesce */
    ) AS Total, 
    strftime('%m',dates) AS Month, 
    strftime('%Y',dates) AS Year 
FROM cte_dates
;
  • Обратите внимание, что это основано на таблице, а не на запросе, который не отражает таблицу.

то есть с таблицей venta: -

enter image description here

результат: -

enter image description here

...