I'm writing a query, data looks like this:
Data:
ID | name | date_completed | version |
---|---|---|---|
1 | Sydney | 2021-01-01 | A |
2 | Melbourne | 2021-01-5 | A |
3 | Sydney | 2021-01-10 | B |
4 | Sydney | 2021-02-01 | A |
5 | Melbourne | 2021-02-07 | A |
6 | Melbourne | 2021-02-13 | A |
My query:
SELECT name
, '01-01-21' AS Date
, (case
when version = 'A' then 'A'
when version = 'B' then 'B'
end) AS 'Type'
, (case
when version = 'A' then count(ID)
when version = 'B' then count(ID)
end) AS 'Count'
FROM table
WHERE date_completed between '2021-01-01' and '2021-01-31'
GROUP BY name, version
UNION
SELECT name
, '01-02-21' AS Date
, (case
when version = 'A' then 'A'
when version = 'B' then 'B'
end) AS 'Type'
, (case
when version = 'A' then count(ID)
when version = 'B' then count(ID)
end) AS 'Count'
FROM table
WHERE date_completed between '2021-02-01' and '2021-02-28'
GROUP BY name, version
Output:
name | date | Type | count |
---|---|---|---|
Sydney | 01-01-21 | A | 1 |
Melbourne | 01-01-21 | A | 1 |
Sydney | 01-01-21 | B | 1 |
Sydney | 01-02-21 | A | 1 |
Melbourne | 01-02-21 | A | 2 |
The issue I'm facing is that because version A/B doesn't exist for some months it will not show a row with count = 0
I'm trying to create an output like this:
name | date | Type | count |
---|---|---|---|
Sydney | 01-01-21 | A | 1 |
Melbourne | 01-01-21 | A | 1 |
Sydney | 01-01-21 | B | 1 |
Melbourne | 01-01-21 | B | 0 |
Sydney | 01-02-21 | A | 1 |
Melbourne | 01-02-21 | A | 2 |
Sydney | 01-02-21 | B | 0 |
Melbourne | 01-02-21 | B | 0 |
Is this something that can be done without having to create a separate table with name, date & type and using LEFT JOIN between the two tables?
Also is there a better way of dealing with querying data within a specific month without having to union multiple select statements?
Thanks
You need to find all combination of name
- month
- version
and then left join
to your table and then perform the count()
If you have individual table of name, version, you may use that instead of finding the distinct value from the table ( select distinct name from tbl
)
with
name_mth_ver as
(
select name, mth_st, mth_en, version
from
(
select distinct name
from tbl
) n
cross join
(
select distinct
mth_st = convert(date, dateadd(month, datediff(month, 0, date_completed), 0)),
mth_en = convert(date, dateadd(month, datediff(month, 0, date_completed) + 1, -1))
from tbl
) m
cross join
(
select distinct version
from tbl
) v
)
select n.name
, n.mth_st AS [Date]
, n.version AS [Type]
, count(t.ID) AS [Count]
from name_mth_ver n
left join tbl t on n.name = t.name
and n.mth_st <= t.date_completed
and n.mth_en >= t.date_completed
and n.version = t.version
group by n.name, n.mth_st, n.version
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.