0
SELECT oi.created_at, count(oi.id_order_item)
FROM order_item oi

The result is the follwoing:

2016-05-05 1562
2016-05-06 3865
2016-05-09 1
...etc

The problem is that I need information for all days even if there were no id_order_item for this date.

Expected result:

Date Quantity
2016-05-05 1562
2016-05-06 3865
2016-05-07 0
2016-05-08 0
2016-05-09 1
3
  • 1
    What version of SQL are you using? SQL Server? MySQL? Oracle? Something else? Commented May 6, 2016 at 15:42
  • 2
    An (incomplete) answer to your problem would be for you to create a table with all your desired dates and using a LEFT JOIN against the query you posted. It would be faster than any solution that involves creating those dates in runtime. Commented May 6, 2016 at 15:50
  • @Edu, it's a complete answer IMHO :-) Commented May 6, 2016 at 15:54

3 Answers 3

2

You can't count something that is not in the database. So you need to generate the missing dates in order to be able to "count" them.

SELECT d.dt, count(oi.id_order_item)
FROM (
   select dt::date
   from generate_series( 
           (select min(created_at) from order_item), 
           (select max(created_at) from order_item), interval '1' day) as x (dt)
) d 
  left join order_item oi on oi.created_at = d.dt
group by d.dt  
order by d.dt;

The query gets the minimum and maximum date form the existing order items.

If you want the count for a specific date range you can remove the sub-selects:

SELECT d.dt, count(oi.id_order_item)
FROM (
   select dt::date
   from generate_series(date '2016-05-01', date '2016-05-31', interval '1' day) as x (dt)
) d 
  left join order_item oi on oi.created_at = d.dt
group by d.dt  
order by d.dt;

SQLFiddle: http://sqlfiddle.com/#!15/49024/5

Sign up to request clarification or add additional context in comments.

Comments

0

Friend, Postgresql Count function ignores Null values. It literally does not consider null values in the column you are searching. For this reason you need to include oi.created_at in a Group By clause

PostgreSql searches row by row sequentially. Because an integral part of your query is Count, and count basically stops the query for that row, your dates with null id_order_item are being ignored. If you group by oi.created_at this column will trump the count and return 0 values for you.

SELECT oi.created_at, count(oi.id_order_item)
FROM order_item oi
Group by io.created_at

From TechontheNet (my most trusted source of information): Because you have listed one column in your SELECT statement that is not encapsulated in the count function, you must use a GROUP BY clause. The department field must, therefore, be listed in the GROUP BY section.

Some info on Count in PostgreSql http://www.postgresqltutorial.com/postgresql-count-function/ http://www.techonthenet.com/postgresql/functions/count.php

Comments

-1

Solution #1 You need Date Table where you stored all date data. Then do a left join depending on period.

Solution #2

WITH DateTable AS
(
    SELECT  DATEADD(dd, 1, CONVERT(DATETIME, GETDATE())) AS CreateDateTime, 1 AS Cnter
    UNION ALL
    SELECT  DATEADD(dd, -1, CreateDateTime), DateTable.Cnter + 1
    FROM    DateTable
    WHERE   DateTable.Cnter + 1 <= 5
)

Generate Temporary table based on your input and then do a left Join.

2 Comments

Agreed It's not complete solution but just an example how to solve the problem. In PostgreSQL, you can do recursive CTE.
This is invalid SQL for Postgres (and you don't need a CTE for this, generate_series() will do just fine)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.