1

I have a database that looks like this

users
phone        created
8001234578   1540231160
9001234578   1540220360
1001234578   1540144760
2001234578   1540058360

Note that the created column is a unix timestamp.

I want to group them by users created on the same day with a count of users, so the above example database should return something like this.

[
  {day: '10/22/2018', count: 2},
  {day: '10/21/2018', count: 1},
  {day: '10/20/2018', count: 1},
]

I tried learning about the to_char command but I couldn't figure it out, this is what I tried:

SELECT 
  to_char(created, 'Day') as day,
COUNT(*) as count
FROM users
WHERE created >= ${startDate} AND created <= ${endDate}
GROUP BY to_char(created, 'Day')

It returned this:

[{day: ' .ay', count: '4'}]
3
  • There is no date or timestamp column in your users table, so how would you know on which day they were created? Commented Oct 22, 2018 at 18:09
  • the created column is the timestamp Commented Oct 22, 2018 at 18:11
  • 1540231160 is not a valid timestamp value in SQL Commented Oct 22, 2018 at 18:47

3 Answers 3

3

First, if it's within your control, you should consider using Postgres's built in TIMESTAMP data type, instead of storing your dates as UNIX timestamps. This will make your queries much easier.

That being said, if you're stuck with using UNIX timestamps (presumably stored as integers), you'll have to convert them to a TIMESTAMP anyways to get what you want. You can use the TO_TIMESTAMP to convert from the UNIX timestamp, and use the DATE_TRUNC function to just get the date portion:

SELECT 
    DATE_TRUNC('day', TO_TIMESTAMP(created)), 
    COUNT(*)
FROM users
GROUP BY DATE_TRUNC('day', TO_TIMESTAMP(created))

Of course, if you're storing the dates as a Postgres TIMESTAMP, it's the same query, but simpler:

SELECT 
    DATE_TRUNC('day', created), 
    COUNT(*)
FROM users
GROUP BY DATE_TRUNC('day', created)
Sign up to request clarification or add additional context in comments.

4 Comments

this works great! Any idea how to include days that have a 0 count as part of the results?
If you need to include days that aren't in your data, you can use something like generate_series (documentation) to create the dates you need.
could you provide an example? I can't figure it out from the documentation
See this answer for information on using generate_series to "fill in the missing dates". If you're still having issues, you might want to create a new question.
2

You can set datetime format, so you got result like this

postgres# select to_char(now(), 'DD Mon YYYY');
   to_char   
-------------
 22 Oct 2018
(1 row)

In your case query will be like this

SELECT 
  to_char(created, 'DD Mon YYYY') as day,
COUNT(*) as count
FROM users
WHERE created >= ${startDate} AND created <= ${endDate}
GROUP BY to_char(created, 'DD Mon YYYY')

Here you can find datetime format specification https://www.postgresql.org/docs/9.6/static/functions-formatting.html#FUNCTIONS-FORMATTING-DATETIME-TABLE

Comments

1
SELECT date_trunc('day', users.created) "day", count(*) as count
FROM users
WHERE created >= ${startDate} AND created <= ${endDate}
GROUP BY 1

6 Comments

I'm getting this error: date_trunc(unknown, double precision) does not exist
The date_trunc function requires a Postgres TIMESTAMP-type value, not a UNIX timestamp type.
So the column is a double rather than an actual timestamp which means you can't use that function. you might be able to do date_trunc('day', to_timestamp(users.created)) "day",
I got it working with this: date_trunc('day', to_timestamp(users.created)) "day", Now I just need to figureout how to get it into the right timezone
It should be UTC, so you can just convert from there
|

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.