Сумма суммы SQL для каждой даты - PullRequest
2 голосов
/ 12 октября 2019

У меня есть таблица под названием «Аренда», в которой я храню данные, подобные следующим:

id | rent_id | start_date | end_date  | amount
---------------------------------------------
1  |   54    | 12-10-2019 | 26-10-2019| 100
2  |   54    | 13-10-2019 | 20-10-2019| 150

Что я ожидаю? Результат типа:

12-10-2019 , amount 100
from 13-10-2019 to 20-10-2019, amount 250
from 21-10-2019 to 26-10-2019, amount 100

В основном я хочу, чтобы за каждый день сумма суммы. Но я также хочу вычислить «дни между».

Таким образом, ожидаемый результат будет:

    id | rent_id | day        |  amount
    ---------------------------------------------
    1  |   54    | 12-10-2019 | 100
    2  |   54    | 13-10-2019 | 250
    3  |   54    | 14-10-2019 | 250

и так далее ...

Я на самом деле бегуследующий sql:

select start_date, ( select sum(amount) from rentals as t2 where t2.start_date <= t1.start_date) as amount from rentals as t1 WHERE rent_id = 54 group by start_date

но результат не такой, как ожидалось ...

Я использую MySQL.

Ответы [ 4 ]

0 голосов
/ 12 октября 2019

Обычное решение этого вопроса заключается в создании календарной таблицы . Это таблица, в которой хранятся все возможные даты, с которыми ваш запрос должен иметь дело. В дикой природе доступны решения для создания и заполнения таблицы, например, вы можете взглянуть на этот пост SO .

Итак, давайте предположим таблицу со следующей структурой и данными:

CREATE TABLE all_dates as (my_date DATE PRIMARY KEY);
INSERT INTO all_dates VALUES
    ('12-10-2019'),
    ('13-10-2019'),
    ('14-10-2019'),
    ...
;

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

SELECT r.rent_id, d.my_date `day`, SUM(amount) amount
FROM all_dates d
INNER JOIN rentals r ON d.my_date BETWEEN r.start_date AND r.end_date
GROUP BY r.rent_id, d.my_date

Примечание: ваше намерение для получения id столбец неясен. Похоже, вы готовы создать новый уникальный идентификатор. Если это так, один из вариантов будет использовать ROW_NUMBER(), как показано ниже:

SELECT ROW_NUMBER() OVER(ORDER BY rent_id, `day`) id, x.*
FROM (
    SELECT r.rent_id, d.my_date `day`, SUM(amount) amount
    FROM all_dates d
    INNER JOIN rentals r ON d.my_date BETWEEN r.start_date AND r.end_date
    GROUP BY r.rent_id, d.my_date
) x
0 голосов
/ 12 октября 2019

Я думаю, что это может помочь с использованием MSSQL

declare @startDate date ='11 Oct 2019'
declare @endDate date ='30 Oct 2019'
declare @rentId nvarchar(50)='54'


select d.Day,d.rent_id,isnull(d.amount,0) as amountPaid, amount = SUM(d.amount) OVER (ORDER BY d.Day) from (
select c.Day,c.id,case when rent_id is null then @rentId else rent_id end as rent_id,c.amount  from (
select * from (
SELECT DATEADD(DAY,number+1,@startDate) [Day]
FROM master..spt_values
WHERE type = 'P'
AND DATEADD(DAY,number+1,@startDate) < @endDate
) a left join (select * from rentals where rent_id=@rentId) b on a.[Day] = b.start_date) c) d
0 голосов
/ 12 октября 2019
select start_date,amount,
amount+lag(amount)over(order by start_date) TOTAL
from  rentals order by start_date
0 голосов
/ 12 октября 2019

https://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=9be7f2c2af8ba8ddae6a14cec807ebd2

with rentals(id, rent_id, start_date, end_date, amount) as (
    SELECT 1 as id,  54 as rent_id,  CAST('2019-10-12' AS DATE) as start_date,  CAST('2019-10-26' AS DATE) as end_date, 100 as amount
    union all 
    SELECT 2 as id,  54 as rent_id,  CAST('2019-10-13' AS DATE) as start_date,  CAST('2019-10-20' AS DATE) as end_date, 150 as amount
),
days(i) as (
    select CAST('2019-10-11' as DATE)
    union all 
    select DATEADD(d,1,i) from days where i<= '2019-10-27'
)

select 
    i ,
    (SELECT ISNULL(SUM(amount),0) FROM rentals WHERE start_date<=i and end_date>=i) as amount
from days

Временное days работает со всеми днями с 11 октября по 27 октября

Решение MySQL (MySQL 8.0):

https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=575b2c4ebe1ed9f05883e87f75f888ef

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