In SQL Server, I have a two tables (tbl1
and tbl2
) as shown below. tbl2
contains a list of all dates. In tbl1
, some of the dates are missing.
tbl1
name nameid count date ----------------------------------------------- apple 1 77 2019-07-29 00:00:00.000 orange 2 129 2019-07-29 00:00:00.000 apple 1 399 2019-08-05 00:00:00.000 orange 2 27 2019-08-05 00:00:00.000 apple 1 122 2019-08-12 00:00:00.000 orange 2 5 2019-08-19 00:00:00.000
tbl2
timeid date 5 2019-07-29 00:00:00.000 4 2019-08-05 00:00:00.000 3 2019-08-12 00:00:00.000 2 2019-08-19 00:00:00.000 1 2019-08-26 00:00:00.000
What I need is the table below. I need to join the two table, populate the name and nameid for the missing dates, and set those counts as 0.
date name nameid count timeid --------------------------------------------------- 2019-07-29 00:00:00.000 apple 1 77 5 2019-07-29 00:00:00.000 orange 2 129 5 2019-08-05 00:00:00.000 apple 1 399 4 2019-08-05 00:00:00.000 orange 2 27 4 2019-08-12 00:00:00.000 apple 1 122 3 2019-08-12 00:00:00.000 orange 2 0 3 2019-08-19 00:00:00.000 apple 1 0 2 2019-08-19 00:00:00.000 orange 2 5 2 2019-08-26 00:00:00.000 apple 1 0 1 2019-08-26 00:00:00.000 orange 2 0 1
I did the following:
SELECT t1.date, name, nameid, count, timeid FROM tbl2 t1 LEFT JOIN tbl1 t2 ON t1.date = t2.date
and got this output:
date name nameid count timeid ---------------------------------------------------------- 2019-07-29 00:00:00.000 apple 1 77 5 2019-07-29 00:00:00.000 orange 2 129 5 2019-08-05 00:00:00.000 apple 1 399 4 2019-08-05 00:00:00.000 orange 2 27 4 2019-08-12 00:00:00.000 apple 1 122 3 2019-08-19 00:00:00.000 orange 2 5 2 2019-08-26 00:00:00.000 NULL NULL NULL 1
It does not seem to be right. Does anyone know how I can generate the desired joined table?
Below is the code to generate tbl1
and tbl2
DROP TABLE IF EXISTS tbl1 CREATE TABLE tbl1 ( name VARCHAR (50) NOT NULL, nameid INT NOT NULL, count INT NOT NULL, date DATETIME ); INSERT INTO tbl1(name, nameid, count, date) VALUES ('apple', 1, 77, '2019-07-29'), ('orange', 2, 129, '2019-07-29'), ('apple', 1, 399, '2019-08-05'), ('orange', 2, 27, '2019-08-05'), ('apple', 1, 122, '2019-08-12'), ('orange', 2, 5, '2019-08-19'); DROP TABLE IF EXISTS tbl2 CREATE TABLE tbl2 ( timeid INT NOT NULL, date DATETIME ); INSERT INTO tbl2(timeid, date) VALUES (5,'2019-07-29'), (4,'2019-08-05'), (3,'2019-08-12'), (2,'2019-08-19'), (1,'2019-08-26');
Advertisement
Answer
To achieve your desired result, you need to cross join the distinct name values from tbl1
with the dates from tbl2
and then LEFT JOIN
that to tbl1
again, using COALESCE
to replace NULL
values of count
with 0:
SELECT t2.date, n.name, n.nameid, COALESCE(t1.count, 0) AS count, t2.timeid FROM tbl2 t2 CROSS APPLY (SELECT DISTINCT name, nameid FROM tbl1) n LEFT JOIN tbl1 t1 ON t1.date = t2.date AND t1.name = n.name ORDER BY t2.date, n.name
Output:
date name nameid count timeid 2019-07-29 00:00:00.000 apple 1 77 5 2019-07-29 00:00:00.000 orange 2 129 5 2019-08-05 00:00:00.000 apple 1 399 4 2019-08-05 00:00:00.000 orange 2 27 4 2019-08-12 00:00:00.000 apple 1 122 3 2019-08-12 00:00:00.000 orange 2 0 3 2019-08-19 00:00:00.000 apple 1 0 2 2019-08-19 00:00:00.000 orange 2 5 2 2019-08-26 00:00:00.000 apple 1 0 1 2019-08-26 00:00:00.000 orange 2 0 1