selecting records without value
I have a problem when I'm trying to reach the desired result. The task looks simple — make a daily count of occurrences of the event for top countries.
The main table looks like this:
id | date | country | col1 | col2 | ...
1 | 2018-01-01 21:21:21 | US | value 1 | value 2 | ...
2 | 2018-01-01 22:32:54 | UK | value 1 | value 2 | ...
From this table, I want to get daily event counts by the country, which is achieved by
SELECT date::DATE AT TIME ZONE 'UTC', country, COALESCE(count(id),0) FROM tab1
GROUP BY 1, 2
The problem comes when there is no event was made by an UK user on 2 January 2018
country_events
date | country | count
2018-01-01 | US | 23
2018-01-01 | UK | 5
2018-01-02 | US | 30
2018-01-02 | UK | 0 -> is desired result, but row is missing
I've tried to generate date series and series of countries which I'm looking for, then CROSS JOIN
these two tables. This helper
with columns date
and country
I've left joined with my result table like
SELECT * FROM helper h
LEFT JOIN country_events c ON c.date::DATE = h.date::DATE AND c.country = h.country
I'm using PostgreSQL.
postgresql join
add a comment |
I have a problem when I'm trying to reach the desired result. The task looks simple — make a daily count of occurrences of the event for top countries.
The main table looks like this:
id | date | country | col1 | col2 | ...
1 | 2018-01-01 21:21:21 | US | value 1 | value 2 | ...
2 | 2018-01-01 22:32:54 | UK | value 1 | value 2 | ...
From this table, I want to get daily event counts by the country, which is achieved by
SELECT date::DATE AT TIME ZONE 'UTC', country, COALESCE(count(id),0) FROM tab1
GROUP BY 1, 2
The problem comes when there is no event was made by an UK user on 2 January 2018
country_events
date | country | count
2018-01-01 | US | 23
2018-01-01 | UK | 5
2018-01-02 | US | 30
2018-01-02 | UK | 0 -> is desired result, but row is missing
I've tried to generate date series and series of countries which I'm looking for, then CROSS JOIN
these two tables. This helper
with columns date
and country
I've left joined with my result table like
SELECT * FROM helper h
LEFT JOIN country_events c ON c.date::DATE = h.date::DATE AND c.country = h.country
I'm using PostgreSQL.
postgresql join
add a comment |
I have a problem when I'm trying to reach the desired result. The task looks simple — make a daily count of occurrences of the event for top countries.
The main table looks like this:
id | date | country | col1 | col2 | ...
1 | 2018-01-01 21:21:21 | US | value 1 | value 2 | ...
2 | 2018-01-01 22:32:54 | UK | value 1 | value 2 | ...
From this table, I want to get daily event counts by the country, which is achieved by
SELECT date::DATE AT TIME ZONE 'UTC', country, COALESCE(count(id),0) FROM tab1
GROUP BY 1, 2
The problem comes when there is no event was made by an UK user on 2 January 2018
country_events
date | country | count
2018-01-01 | US | 23
2018-01-01 | UK | 5
2018-01-02 | US | 30
2018-01-02 | UK | 0 -> is desired result, but row is missing
I've tried to generate date series and series of countries which I'm looking for, then CROSS JOIN
these two tables. This helper
with columns date
and country
I've left joined with my result table like
SELECT * FROM helper h
LEFT JOIN country_events c ON c.date::DATE = h.date::DATE AND c.country = h.country
I'm using PostgreSQL.
postgresql join
I have a problem when I'm trying to reach the desired result. The task looks simple — make a daily count of occurrences of the event for top countries.
The main table looks like this:
id | date | country | col1 | col2 | ...
1 | 2018-01-01 21:21:21 | US | value 1 | value 2 | ...
2 | 2018-01-01 22:32:54 | UK | value 1 | value 2 | ...
From this table, I want to get daily event counts by the country, which is achieved by
SELECT date::DATE AT TIME ZONE 'UTC', country, COALESCE(count(id),0) FROM tab1
GROUP BY 1, 2
The problem comes when there is no event was made by an UK user on 2 January 2018
country_events
date | country | count
2018-01-01 | US | 23
2018-01-01 | UK | 5
2018-01-02 | US | 30
2018-01-02 | UK | 0 -> is desired result, but row is missing
I've tried to generate date series and series of countries which I'm looking for, then CROSS JOIN
these two tables. This helper
with columns date
and country
I've left joined with my result table like
SELECT * FROM helper h
LEFT JOIN country_events c ON c.date::DATE = h.date::DATE AND c.country = h.country
I'm using PostgreSQL.
postgresql join
postgresql join
edited Nov 15 '18 at 18:27
Laurenz Albe
51.1k103050
51.1k103050
asked Nov 15 '18 at 18:09
skutikskutik
5217
5217
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
You need an outer join, not a cross join:
SELECT tab1.date::date, tab1.country, coalesce(count(*), 0)
FROM generate_series(TIMESTAMP '2018-01-01 00:00:00',
TIMESTAMP '2018-01-31 00:00:00',
INTERVAL '1 day') AS ts(d)
LEFT JOIN tab1 ON tab1.date >= ts.d AND tab1.date < ts.d + INTERVAL '1 day'
GROUP BY tab1.date::date, tab1.country
ORDER BY tab1.date::date, tab1.country;
This will give the desired list for January 2018.
It's not working. Perhaps because when I make select from the tab1, there is no record date for this date, so row is not created like date | country | count 2018-01-01 | UK | 5 2018-01-03 | UK | 7 in this case, there is no way how to join tab1 select when there is no combination of 2018-01-01 with UK value... Isn't it?
– skutik
Nov 16 '18 at 7:41
Can you specify "it is not working"? Are there errors? Results different from what you described in your question? It might help if you add theCREATE TABLE
statement fortab1
to the question.
– Laurenz Albe
Nov 16 '18 at 9:35
I'm sorry. There is no error but also no progress. Little progress was when I've changedtab1.date
forts.d
but it can be caused by usingON tab1.date = ts.d
. With this change, I've got the result like this2018-01-02 | NULL | 0
-> theUK
country is missing. Is any approach how to achieve2018-01-02 | UK | 0
without makingSELECT
for each country withCASE WHEN country IS NULL THEN 'UK' ELSE country END
and then union them all?
– skutik
Nov 16 '18 at 11:34
I don't understand. How was yourCREATE TABLE
statement?
– Laurenz Albe
Nov 16 '18 at 11:51
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53325507%2fselecting-records-without-value%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
You need an outer join, not a cross join:
SELECT tab1.date::date, tab1.country, coalesce(count(*), 0)
FROM generate_series(TIMESTAMP '2018-01-01 00:00:00',
TIMESTAMP '2018-01-31 00:00:00',
INTERVAL '1 day') AS ts(d)
LEFT JOIN tab1 ON tab1.date >= ts.d AND tab1.date < ts.d + INTERVAL '1 day'
GROUP BY tab1.date::date, tab1.country
ORDER BY tab1.date::date, tab1.country;
This will give the desired list for January 2018.
It's not working. Perhaps because when I make select from the tab1, there is no record date for this date, so row is not created like date | country | count 2018-01-01 | UK | 5 2018-01-03 | UK | 7 in this case, there is no way how to join tab1 select when there is no combination of 2018-01-01 with UK value... Isn't it?
– skutik
Nov 16 '18 at 7:41
Can you specify "it is not working"? Are there errors? Results different from what you described in your question? It might help if you add theCREATE TABLE
statement fortab1
to the question.
– Laurenz Albe
Nov 16 '18 at 9:35
I'm sorry. There is no error but also no progress. Little progress was when I've changedtab1.date
forts.d
but it can be caused by usingON tab1.date = ts.d
. With this change, I've got the result like this2018-01-02 | NULL | 0
-> theUK
country is missing. Is any approach how to achieve2018-01-02 | UK | 0
without makingSELECT
for each country withCASE WHEN country IS NULL THEN 'UK' ELSE country END
and then union them all?
– skutik
Nov 16 '18 at 11:34
I don't understand. How was yourCREATE TABLE
statement?
– Laurenz Albe
Nov 16 '18 at 11:51
add a comment |
You need an outer join, not a cross join:
SELECT tab1.date::date, tab1.country, coalesce(count(*), 0)
FROM generate_series(TIMESTAMP '2018-01-01 00:00:00',
TIMESTAMP '2018-01-31 00:00:00',
INTERVAL '1 day') AS ts(d)
LEFT JOIN tab1 ON tab1.date >= ts.d AND tab1.date < ts.d + INTERVAL '1 day'
GROUP BY tab1.date::date, tab1.country
ORDER BY tab1.date::date, tab1.country;
This will give the desired list for January 2018.
It's not working. Perhaps because when I make select from the tab1, there is no record date for this date, so row is not created like date | country | count 2018-01-01 | UK | 5 2018-01-03 | UK | 7 in this case, there is no way how to join tab1 select when there is no combination of 2018-01-01 with UK value... Isn't it?
– skutik
Nov 16 '18 at 7:41
Can you specify "it is not working"? Are there errors? Results different from what you described in your question? It might help if you add theCREATE TABLE
statement fortab1
to the question.
– Laurenz Albe
Nov 16 '18 at 9:35
I'm sorry. There is no error but also no progress. Little progress was when I've changedtab1.date
forts.d
but it can be caused by usingON tab1.date = ts.d
. With this change, I've got the result like this2018-01-02 | NULL | 0
-> theUK
country is missing. Is any approach how to achieve2018-01-02 | UK | 0
without makingSELECT
for each country withCASE WHEN country IS NULL THEN 'UK' ELSE country END
and then union them all?
– skutik
Nov 16 '18 at 11:34
I don't understand. How was yourCREATE TABLE
statement?
– Laurenz Albe
Nov 16 '18 at 11:51
add a comment |
You need an outer join, not a cross join:
SELECT tab1.date::date, tab1.country, coalesce(count(*), 0)
FROM generate_series(TIMESTAMP '2018-01-01 00:00:00',
TIMESTAMP '2018-01-31 00:00:00',
INTERVAL '1 day') AS ts(d)
LEFT JOIN tab1 ON tab1.date >= ts.d AND tab1.date < ts.d + INTERVAL '1 day'
GROUP BY tab1.date::date, tab1.country
ORDER BY tab1.date::date, tab1.country;
This will give the desired list for January 2018.
You need an outer join, not a cross join:
SELECT tab1.date::date, tab1.country, coalesce(count(*), 0)
FROM generate_series(TIMESTAMP '2018-01-01 00:00:00',
TIMESTAMP '2018-01-31 00:00:00',
INTERVAL '1 day') AS ts(d)
LEFT JOIN tab1 ON tab1.date >= ts.d AND tab1.date < ts.d + INTERVAL '1 day'
GROUP BY tab1.date::date, tab1.country
ORDER BY tab1.date::date, tab1.country;
This will give the desired list for January 2018.
answered Nov 15 '18 at 18:24
Laurenz AlbeLaurenz Albe
51.1k103050
51.1k103050
It's not working. Perhaps because when I make select from the tab1, there is no record date for this date, so row is not created like date | country | count 2018-01-01 | UK | 5 2018-01-03 | UK | 7 in this case, there is no way how to join tab1 select when there is no combination of 2018-01-01 with UK value... Isn't it?
– skutik
Nov 16 '18 at 7:41
Can you specify "it is not working"? Are there errors? Results different from what you described in your question? It might help if you add theCREATE TABLE
statement fortab1
to the question.
– Laurenz Albe
Nov 16 '18 at 9:35
I'm sorry. There is no error but also no progress. Little progress was when I've changedtab1.date
forts.d
but it can be caused by usingON tab1.date = ts.d
. With this change, I've got the result like this2018-01-02 | NULL | 0
-> theUK
country is missing. Is any approach how to achieve2018-01-02 | UK | 0
without makingSELECT
for each country withCASE WHEN country IS NULL THEN 'UK' ELSE country END
and then union them all?
– skutik
Nov 16 '18 at 11:34
I don't understand. How was yourCREATE TABLE
statement?
– Laurenz Albe
Nov 16 '18 at 11:51
add a comment |
It's not working. Perhaps because when I make select from the tab1, there is no record date for this date, so row is not created like date | country | count 2018-01-01 | UK | 5 2018-01-03 | UK | 7 in this case, there is no way how to join tab1 select when there is no combination of 2018-01-01 with UK value... Isn't it?
– skutik
Nov 16 '18 at 7:41
Can you specify "it is not working"? Are there errors? Results different from what you described in your question? It might help if you add theCREATE TABLE
statement fortab1
to the question.
– Laurenz Albe
Nov 16 '18 at 9:35
I'm sorry. There is no error but also no progress. Little progress was when I've changedtab1.date
forts.d
but it can be caused by usingON tab1.date = ts.d
. With this change, I've got the result like this2018-01-02 | NULL | 0
-> theUK
country is missing. Is any approach how to achieve2018-01-02 | UK | 0
without makingSELECT
for each country withCASE WHEN country IS NULL THEN 'UK' ELSE country END
and then union them all?
– skutik
Nov 16 '18 at 11:34
I don't understand. How was yourCREATE TABLE
statement?
– Laurenz Albe
Nov 16 '18 at 11:51
It's not working. Perhaps because when I make select from the tab1, there is no record date for this date, so row is not created like date | country | count 2018-01-01 | UK | 5 2018-01-03 | UK | 7 in this case, there is no way how to join tab1 select when there is no combination of 2018-01-01 with UK value... Isn't it?
– skutik
Nov 16 '18 at 7:41
It's not working. Perhaps because when I make select from the tab1, there is no record date for this date, so row is not created like date | country | count 2018-01-01 | UK | 5 2018-01-03 | UK | 7 in this case, there is no way how to join tab1 select when there is no combination of 2018-01-01 with UK value... Isn't it?
– skutik
Nov 16 '18 at 7:41
Can you specify "it is not working"? Are there errors? Results different from what you described in your question? It might help if you add the
CREATE TABLE
statement for tab1
to the question.– Laurenz Albe
Nov 16 '18 at 9:35
Can you specify "it is not working"? Are there errors? Results different from what you described in your question? It might help if you add the
CREATE TABLE
statement for tab1
to the question.– Laurenz Albe
Nov 16 '18 at 9:35
I'm sorry. There is no error but also no progress. Little progress was when I've changed
tab1.date
for ts.d
but it can be caused by using ON tab1.date = ts.d
. With this change, I've got the result like this 2018-01-02 | NULL | 0
-> the UK
country is missing. Is any approach how to achieve 2018-01-02 | UK | 0
without making SELECT
for each country with CASE WHEN country IS NULL THEN 'UK' ELSE country END
and then union them all?– skutik
Nov 16 '18 at 11:34
I'm sorry. There is no error but also no progress. Little progress was when I've changed
tab1.date
for ts.d
but it can be caused by using ON tab1.date = ts.d
. With this change, I've got the result like this 2018-01-02 | NULL | 0
-> the UK
country is missing. Is any approach how to achieve 2018-01-02 | UK | 0
without making SELECT
for each country with CASE WHEN country IS NULL THEN 'UK' ELSE country END
and then union them all?– skutik
Nov 16 '18 at 11:34
I don't understand. How was your
CREATE TABLE
statement?– Laurenz Albe
Nov 16 '18 at 11:51
I don't understand. How was your
CREATE TABLE
statement?– Laurenz Albe
Nov 16 '18 at 11:51
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53325507%2fselecting-records-without-value%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown