MS SQL case inside count - mysql

I have zero experience in MS SQL and I'm tearing my hair out trying to convert my MySQL query:
select
m.Customer,
count(if(c.AtFault="Me",1,null)) 'MeLate',
count(if(c.AtFault="You",1,null)) 'YouLate',
count(*) 'Total'
from m
left join r on m.OrderNumber = r.OrderNumber
left join c on r.ReasonCodeID = c.ID
group by m.Customer
This is what I'm trying to run on MS SQL:
select
m.Customer
count(CASE WHEN c.AtFault="Me" THEN 1 ELSE null) 'MeLate',
count(CASE WHEN c.AtFault="You" THEN 1 ELSE null) 'YouLate',
count(*) 'Total'
from m
left join r on m.OrderNumber = r.OrderNumber
left join c on r.ReasonCodeID = c.ID
group by m.Customer
but this throws the uninformative error:
SQL Error (102): Incorrect syntax near ')'.

Three errors:
You are missing the END at the end of CASE WHEN.
You must use single quote instead double.
Forgot the comma after m.Customer
Try this:
select
m.Customer,
count(CASE WHEN c.AtFault='Me' THEN 1 ELSE null END) MeLate,
count(CASE WHEN c.AtFault='You' THEN 1 ELSE null END) YouLate,
count(*) Total
from m
left join r on m.OrderNumber = r.OrderNumber
left join c on r.ReasonCodeID = c.ID
group by m.Customer

end is missing there and you can try sum instead of count
select
m.Customer,
sum(CASE WHEN c.AtFault='Me' THEN 1 ELSE 0 end) MeLate,
sum(CASE WHEN c.AtFault='You' THEN 1 ELSE 0 end) YouLate,
count(*) Total
from m
left join r on m.OrderNumber = r.OrderNumber
left join c on r.ReasonCodeID = c.ID
group by m.Customer

Related

Translate MYSQL query to HQL using multiple JOINS

everyone.
I am using grails 3.3.0.M2 framework with mysql as data-source the following sql query is working as expected
SELECT
c.name,
SUM(CASE
WHEN t.status = 'open' THEN 1
ELSE 0
END) 'open',
SUM(CASE
WHEN t.status = 'pending' THEN 1
ELSE 0
END) 'in progress',
SUM(CASE
WHEN t.status = 'closed' THEN 1
ELSE 0
END) 'closed'
FROM
tickets t
INNER JOIN
users u ON t.user_id = u.id
INNER JOIN
user_coordinations uc ON uc.user_id = u.id
INNER JOIN
coordinations c ON c.id = uc.coordination_id
GROUP BY 1
I translated to HQL using implicit JOIN but I am getting the wrong results, here is the hql query:
SELECT
c.name,
SUM(CASE
WHEN t.status = 'open' THEN 1
ELSE 0
END),
SUM(CASE
WHEN t.status = 'pending' THEN 1
ELSE 0
END),
SUM(CASE
WHEN t.status = 'closed' THEN 1
ELSE 0
END)
FROM
Ticket t, User u, UserCoordination uc, Coordination c
WHERE
MONTH(t.dateCreated) = :month
GROUP BY 1
In order to get the right results stack overflow users help me to understand that the query needs to use explicit JOINS, here the question: Group by a field that does not belongs to the consulted table
Right now I am trying with the following query:
SELECT
c.name,
SUM(CASE
WHEN t.status = 'open' THEN 1
ELSE 0
END),
SUM(CASE
WHEN t.status = 'pending' THEN 1
ELSE 0
END),
SUM(CASE
WHEN t.status = 'closed' THEN 1
ELSE 0
END)
FROM
Ticket t
INNER JOIN
User u
INNER JOIN
UserCoordination uc
INNER JOIN
Coordination c
WHERE
MONTH(t.dateCreated) = :month
GROUP BY 1
But i am getting a com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException with the caused message You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'inner join user_coordinations usercoordi2_ on inner join coordinations coordinat' at line 1
Thanks for your help and time
SELECT new map(
c.name as name,
(CASE
WHEN t.status = 'open' THEN 1
ELSE 0
END) as open,
(CASE
WHEN t.status = 'pending' THEN 1
ELSE 0
END) as pending,
(CASE
WHEN t.status = 'closed' THEN 1
ELSE 0
END) as closed,
SUM(open) as openSum,
SUM(pending) as pendingSum,
SUM(closed) as closedSum
)
FROM
Ticket t
left join t.user u left join u.userCoordination uc left join uc.coordination c
WHERE
MONTH(t.dateCreated) = :month
//GROUP BY 1
What you had had lots missing above is more like what you need, you need
select new map(i.item as item... if you compare the basics of this with what you had and what i tried to do you can see why you had errors.
unsure about your group by it should be group by something. Wasn't sure by inner join if you just meant a join if that was the case leave out all the left join since left join attempts to connect and get any null hasMany relations etc.

how to select count of specific value while joining two tables

here i am joining two tables and this code fails to get the count of c.status
when c.status='Absent'
SELECT d.empReferenceID,
Count(c.status)
FROM emp_tbl d
LEFT JOIN empattendance c
on d.empReferenceID = c.RefrenceID
and c.status='PRESENT'
and month(c.CreatedOn)=5
and year(c.CreatedOn)=2017
where c.RefrenceID not in ('2075671')
GROUP BY d.empReferenceID;
Don't put conditions on an outer-joined table in the WHERE clause. Your where c.RefrenceID not in ('2075671') dismisses all outer-joined records and turns the join into an inner join.
Maybe you are looking for conditional aggregation, where you count different statuses and show the counts in the same result row:
SELECT d.empReferenceID,
Count(c.status) AS count_all,
Sum(c.status = 'PRESENT') AS count_present,
Sum(c.status = 'Absent') AS count_absent
FROM emp_tbl d
LEFT JOIN empattendance c
ON d.empReferenceID = c.RefrenceID
AND month(c.CreatedOn)=5
AND year(c.CreatedOn)=2017
WHERE d.empReferenceID not in ('2075671')
GROUP BY d.empReferenceID;
The SUM lines make use of MySQL's true = 1/ false = 0 by the way. You'd achieve the same with standard SQL: Sum(CASE WHEN c.status = 'PRESENT' THEN 1 ELSE 0 END) or Count(CASE WHEN c.status = 'PRESENT' THEN 1 END).

Combine Union ALL with Inner Join Statement

I have a problem how to combine the sql statements (inner join and union all. as a Newbie in SQL. Hopefully all members can help me to solve the problems.attached herewith the SQL. The leave_Trx and leave_History contain same values that need to be union. Thank you.
select m.name, t.startdt, t.enddt,t.noday,t.createdDT,
(case when t.approveST = 'Y' then 'Approved' when t.approveST = 'N' then 'Not Approved' else 'Pending' end) as appST
from leave_Trx t
inner join leave_MType m on m.typeID = t.trxID
inner join hr_personaldata b on b.pers_ID = #pers_ID
where year(t.startdt) = #yyear
and b.pers_ID = #pers_ID and b.pers_name LIKE '%'+#pers_name+'%'
and b.pers_compID LIKE ''+#compID+''
union all
select * from leave_History h
where year(h.startdt) = #yyear and h.status = 'A'
ORDER BY t.startdt
select t.pers_ID,t.startdt, t.enddt,t.noday,t.createdDT,
(case when t.approveST = 'Y' then 'Approved' when t.approveST = 'N' then 'Not Approved' else 'Pending' end) as appST
from leave_Trx t
inner join leave_MType m on m.typeID = t.pers_ID
inner join hr_personaldata l on l.pers_ID = #pers_ID
where year(t.startdt) = #yyear and t.status = 'A'
union all
select h.pers_ID, h.startdt, h.enddt,h.noday,h.createdDT,
(case when h.approveST = 'Y' then 'Approved' when h.approveST = 'N' then 'Not Approved' else 'Pending' end) as appST
from leave_History h
inner join leave_MType m on m.typeID = h.pers_ID
inner join hr_personaldata b on b.pers_ID = #pers_ID
where year(h.startdt) = #yyear and h.status = 'A'

Why is left outer join failing here for me?

I see nothing wrong here, but why does this give me
/* SQL Error (1064): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'left outer join votes on items.id = votes.parent and votes.userid = 1 group by i' at line 2 */
select maxVotes, sum(case when coalesce(votes.id, 0) then 1 else 0 end) votesCast from items where type = 'marker'
left outer join votes on items.id = votes.parent and votes.userid = 1 group by items.id;
I'm doing this using mySql.
Change to
select maxVotes,
sum(case when coalesce(votes.id, 0) then 1 else 0 end) votesCast
from items left outer join votes -- <-- your JOIN clause should go here
on items.id = votes.parent
and votes.userid = 1
where type = 'marker' -- <-- and WHERE here
group by items.id;
On a side note: even though MySql allows to specify a field (in your case maxVotes) in SELECT that is not a part of GROUP BY it's a not a good thing to do. You need to apply an aggregate function to that field (MAX, MIN...). There is no way to tell which value of maxVotes to grab when you do GROUP BY items.id.
Move your JOIN before WHERE clause:
select maxVotes, sum(case when coalesce(votes.id, 0) then 1 else 0 end) votesCast
from items
left outer join votes on items.id = votes.parent and votes.userid = 1
where type = 'marker'
group by items.id;
Try this...
select maxVotes,
sum(case when coalesce(votes.id, 0) then 1 else 0 end) votesCast
from items
left outer join votes on items.id = votes.parent and votes.userid = 1
where items.type = 'marker' group by items.id;

How to create multiple counts in a mysql statement

I have some trouble to count more than 2 counts in mysql statement.
My count(b.entry_id) as totalbooking wont work. What have i done wrong? Is the statement setup also correctly made​​?
This is how i tried:
"SELECT
t.restaurant_id as restaurant_id, ct.title as title,
count(DISTINCT t.cardid) as totalmembers,
count(t.restaurant_id) as totaltransactions,
count(b.entry_id) as totalbooking
from transactions as t
inner join exp_menucard_booking as b on (t.restaurant_id = b.entry_id)
inner join exp_channel_titles as ct on (t.restaurant_id = ct.entry_id)
inner JOIN exp_channel_data as cd on (ct.entry_id = cd.entry_id)
where t.cardid != 88888888 and ct.status = 'open'
group by t.restaurant_id
order by ct.title asc";
Use this pattern to count subsets of the total rowset:
sum( case when ColumnToBeTested = trueCondition then 1 else 0 end) as SubCount