简体   繁体   中英

Add empty date row to query result

There are 6 kind of ticket types. User will enter starting date and ending date. Then I have to show how many each type of tickets are on each days between those 2 date.

ticket table: id (int), type_id (int), created_at (date), and more fields

Input: date_begin, date_end
Output: rows > dates. columns > date, total_amount, and each types

My current query:

SELECT
    DATE(ticket.created_date) as date,
    SUM(IF(ticket.created_date, 1, 0)) as total,
    SUM(IF(ticket.type_id is Null, 1, 0)) as total0,
    SUM(IF(ticket.type_id = 1, 1, 0)) as total1,
    SUM(IF(ticket.type_id = 2, 1, 0)) as total2,
    SUM(IF(ticket.type_id = 3, 1, 0)) as total3,
    SUM(IF(ticket.type_id = 4, 1, 0)) as total4,
    SUM(IF(ticket.type_id = 5, 1, 0)) as total5
FROM
    ticket
JOIN 
    ticket_type ON ticket_type.id = ticket.type_id
WHERE
    DATE(ticket.created_date) BETWEEN '2015-06-12' AND '2015-06-22'
GROUP BY
    DATE(ticket.created_date)

Current output:

在此处输入图片说明

Desired output:
在此处输入图片说明

As you see today is 2015-06-19. So my database currently have data only until right now (today). But if user's end_date is in future, i want get rows until that day, and datas will be 0.

First of all you must create the funcion "explodeDates". You have an example of definition on the link on my previous coment. However, if you are using SqlServer, you can use this code:

CREATE FUNCTION explodeDates(@firstDate DATE, @secondDate DATE)
RETURNS 
@mytable TABLE 
(
    mydate DATE
)
AS
BEGIN
    WHILE @firstDate < @secondDate 
    BEGIN
        INSERT INTO @mytable(mydate) VALUES (@firstDate);

        SET @firstDate = DATEADD(day, 1, @firstdate);
    END

    RETURN 
END
GO

When you had defined that function, you can call it like this:

SELECT * FROM dbo.explodeDates('01/01/2015', '31/01/2015')

After that you, only have to define your initial query like this:

SELECT
    d.mydate as date,
    SUM(IF(ticket.created_date, 1, 0)) as total,
    SUM(IF(ticket.type_id is Null, 1, 0)) as total0,
    SUM(IF(ticket.type_id = 1, 1, 0)) as total1,
    SUM(IF(ticket.type_id = 2, 1, 0)) as total2,
    SUM(IF(ticket.type_id = 3, 1, 0)) as total3,
    SUM(IF(ticket.type_id = 4, 1, 0)) as total4,
    SUM(IF(ticket.type_id = 5, 1, 0)) as total5
FROM
    dbo.explodeDates('12/06/2015', '22/06/2015') d
    LEFT JOIN ticket t ON t.created_date = d.mydate
    LEFT JOIN ticket_type ON ticket_type.id = ticket.type_id

GROUP BY
    d.mydate

Firstly, This has to be validated at the fronted. Also, if ever such a query comes, I think you output is valid. How can you show tickets of future date (Which are not created). I assume these are not movie tickets.. :P

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM