patternsqlMinor
Incorrect result when using 'case when count()=0' & 'where'
Viewed 0 times
caseresultincorrectwhereusingwhencount
Problem
I would very appreciate if someone could help me out with this query.
I can't seem to get the correct result when using
I work with SQL Server, with a DB of a system that is alike "Facebook".
I'm trying to write a query that shows the email address, tagging status & the number of posts posted in the past month.
The tagging status should be as follows:
If tagging 1-2 posts - display "few"
If tagging 3-5 posts - display "medium"
If tagging 5+ posts - display "many"
If not tagging at all - display "none".
Below is the query I wrote. The problem with the query I wrote is that because of the condition in WHERE, I will never receive 'none'.
How can I change the query in order to display the correct result?
Data for example:
The required input should be: Kelly-'none', Lilly-'none', Nelly-'few', Owen-'none'.
```
create table Users
(
Mail nvarchar (20) primary key check(Mail like '_%@_%._%' and (Mail like '%[0-9]%' Or Mail like '%[a-z]%'Or Mail like '%[A-Z]%')),
Password nvarchar (8) check (Password like '%[0-9]%' and Password like '%[az]%' and len(password) =18) not null,
JoinDate date check (JoinDate<=getdate()) not null,
Gender nchar(1) check(Gender = 'F' or Gender = 'M' or Gender = 'O'),
NickName nvarchar(20),
Photo nvarchar(20),
Phone bigint check (Phone like '%[0-9]%' and len(Phone) <= 10) not null
)
INSERT INTO Users
VALUES
('Kelly@gmail.com','k1000000','Kelly','Ka','1992-05-15','2016-09-04','F','Kelly','Kelly.jpg','546296100'),
('Lilly@gmail.com','l1101111','Lilly','La','1999-04-03','2012
I can't seem to get the correct result when using
case when count()=0 & whereI work with SQL Server, with a DB of a system that is alike "Facebook".
I'm trying to write a query that shows the email address, tagging status & the number of posts posted in the past month.
The tagging status should be as follows:
If tagging 1-2 posts - display "few"
If tagging 3-5 posts - display "medium"
If tagging 5+ posts - display "many"
If not tagging at all - display "none".
Below is the query I wrote. The problem with the query I wrote is that because of the condition in WHERE, I will never receive 'none'.
How can I change the query in order to display the correct result?
select U.Mail, count(P.ID) as PostCount,
case
when count(P.ID) = 0 then 'none'
when count(P.ID) <= 2 then 'few'
when count(P.ID) <= 5 then 'medium'
else 'many'
end PostCountCategory
from Users U
left join Tagging T on U.Mail = T.Mail
left join Post P on T.IDPost = P.ID
where datediff(day,P.DatePosted,getdate()) <= 30 --Because of this condition I would never get 'none'
group by U.Mail, U.GenderData for example:
The required input should be: Kelly-'none', Lilly-'none', Nelly-'few', Owen-'none'.
```
create table Users
(
Mail nvarchar (20) primary key check(Mail like '_%@_%._%' and (Mail like '%[0-9]%' Or Mail like '%[a-z]%'Or Mail like '%[A-Z]%')),
Password nvarchar (8) check (Password like '%[0-9]%' and Password like '%[az]%' and len(password) =18) not null,
JoinDate date check (JoinDate<=getdate()) not null,
Gender nchar(1) check(Gender = 'F' or Gender = 'M' or Gender = 'O'),
NickName nvarchar(20),
Photo nvarchar(20),
Phone bigint check (Phone like '%[0-9]%' and len(Phone) <= 10) not null
)
INSERT INTO Users
VALUES
('Kelly@gmail.com','k1000000','Kelly','Ka','1992-05-15','2016-09-04','F','Kelly','Kelly.jpg','546296100'),
('Lilly@gmail.com','l1101111','Lilly','La','1999-04-03','2012
Solution
just move where conditions to the join part:
also your original condition doesn't alloow SQL Server to use index seek. It would be better to rewrite it this way:
select U.Mail, count(P.ID) as PostCount,
case
when count(P.ID) = 0 then 'none'
when count(P.ID) <= 2 then 'few'
when count(P.ID) <= 5 then 'medium'
else 'many'
end PostCountCategory
from Users U
left join Tagging T on U.Mail = T.Mail
left join Post P on T.IDPost = P.ID AND datediff(day,P.DatePosted,getdate()) <= 30
group by U.Mail, U.Genderalso your original condition doesn't alloow SQL Server to use index seek. It would be better to rewrite it this way:
P.DatePosted >= dateadd(day, -30, cast(getdate() as date))Code Snippets
select U.Mail, count(P.ID) as PostCount,
case
when count(P.ID) = 0 then 'none'
when count(P.ID) <= 2 then 'few'
when count(P.ID) <= 5 then 'medium'
else 'many'
end PostCountCategory
from Users U
left join Tagging T on U.Mail = T.Mail
left join Post P on T.IDPost = P.ID AND datediff(day,P.DatePosted,getdate()) <= 30
group by U.Mail, U.GenderP.DatePosted >= dateadd(day, -30, cast(getdate() as date))Context
StackExchange Database Administrators Q#266750, answer score: 6
Revisions (0)
No revisions yet.