Count invitation response against events and response codes - mysql

I have this table for Response Codes:
And this table for invitations:
My query so far gives this:
While I want to achieve this:
MY QUERY:
SELECT
i.eventId
,code.responseCode
,COUNT(i.attendeeResponse) responseCount
FROM invitations i
LEFT JOIN response_codes code
ON code.responseCode = i.attendeeResponse
GROUP BY i.eventId, code.responseCode, i.attendeeResponse;
SQLFiddle

You need to construct a cartesian product of all eventIds and responseCodes at first (you can achieve it with join without condition):
select c.eventId
, c.responseCode
, count( i.attendeeResponse ) as responseCount
from ( select distinct t1.responseCode
, t2.eventId
from `response_codes` t1
join `invitations` t2 ) c
left join `invitations` i on c.responseCode = i.attendeeResponse and c.eventId = i.eventId
group by c.eventId, c.responseCode;
SQLFiddle

You need to cross join the responsecode table to get the all combinations of eventid and responsecode.
SQL Fiddle
SELECT distinct
i.eventId
,code.responseCode
,case when t.responseCount is null then 0
else t.responsecount end rcount
FROM invitations i
cross JOIN response_codes code
left join
(SELECT i.eventId
,code.responseCode
,COUNT(i.attendeeResponse) responseCount
FROM invitations i
JOIN response_codes code
ON code.responseCode = i.attendeeResponse
group by i.eventid, code.responsecode) t
on t.responsecode =code.responsecode and t.eventid = i.eventid
order by i.eventid, code.responsecode desc

Another lazy way could be:
SELECT B.EVENTID,A.RESPONSECODE,
IFNULL((SELECT COUNT(*) FROM INVITATIONS C WHERE C.EVENTID = B.EVENTID AND C.ATTENDEERESPONSE = A.RESPONSECODE),0) AS 'responseCount'
FROM
RESPONSE_CODES A,
INVITATIONS B
GROUP BY A.RESPONSECODE,B.EVENTID
ORDER BY EVENTID ASC,RESPONSECODE DESC
SQL Fiddle

Related

How to join with having in mysql?

All, I face a problem with join mysql. I want to get a result with count a unique amount of staff_id field using GROUP BY. If I run this query I got result as I want at one step.
SELECT id,staff_id,note,warning_date FROM tbl_warning GROUP BY staff_id HAVING (count(staff_id) > 0);
The next I want to join two more tables to get field such as tbl_employment.com_id as comid, tbl_staff.name, tbl_staff.gender but the result are duplicate.
`SELECT` `tbl_warning`.`id`, `tbl_warning`.`staff_id`, `tbl_warning`.`note`, `tbl_warning`.`warning_date`,`tbl_employment`.`com_id` as `comid`, `tbl_staff`.`name`, `tbl_staff`.`gender` FROM `tbl_warning`
JOIN `tbl_employment` ON `tbl_employment`.`staff_id` = `tbl_warning`.`staff_id`
JOIN `tbl_staff` ON `tbl_staff`.`id` = `tbl_warning`.`staff_id`
HAVING (SELECT `staff_id` FROM `tbl_warning` GROUP BY `staff_id` HAVING (count(staff_id) > 1));
I want unique result same first screenshot.
Thank you!
You should join to a subquery which finds the matching staff by count:
SELECT
t1.id,
t1.staff_id,
t1.note,
t1.warning_date,
t2.com_id as `comid`,
t3.name,
t3.gender
FROM tbl_warning t1
INNER JOIN tbl_employment t2
ON t2.staff_id = t1.staff_id
INNER JOIN tbl_staff t3
ON t3.id = t1.staff_id
INNER JOIN
(
SELECT staff_id
FROM tbl_warning
GROUP BY staff_id
HAVING COUNT(*) > 1
) t
ON t.staff_id = t2.staff_id;

Send request GROUP by

How to group the data so that the sorting is respected?
SELECT tt.id_img,
tt.number_public,
tt.time_post,
tt.id_public
FROM (SELECT
`number_public`,
`id_img`,
`time_post`,
birthday_publics.id_public
FROM birthday_time_post LEFT JOIN birthday_publics
ON birthday_publics.id = birthday_time_post.number_public
WHERE birthday_time_post.time_post IN(
SELECT MIN(time_post)
FROM birthday_time_post
GROUP BY number_public
)
ORDER BY time_post
) tt
Sort by column time_post
Photo request
enter image description here
This should be enough
SELECT
b.`number_public`,
b.`id_img`,
b.`time_post`,
birthday_publics.id_public
FROM birthday_time_post b
INNER JOIN (
SELECT MIN(time_post) min_time
FROM birthday_time_post
GROUP BY number_public
) t on t.min_time = b.time_post
LEFT JOIN birthday_publics ON birthday_publics.id =b.number_public
order by b.time_post

Mysql Select unique record based on multiple columns and display only group and sum amount

Hi I am trying to query a table that conatains multiple duplicates on Code,Amount and Status How will I do this if I only one to get a result group according to the client_group name and get the sum of amount under that group
SELECT `client`.`client_group`
, FORMAT(SUM(`Data_result`.`Data_result_amount` ),2) as sum
FROM
`qwer`.`Data_result`
INNER JOIN `qwer`.`Data`
ON (`Data_result`.`Data_result_lead` = `Data`.`Data_id`)
INNER JOIN `qwer`.`Data_status`
ON (`Data_result`.`Data_result_status_id` = `Data_status`.`Data_status_id`)
INNER JOIN `qwer`.`client`
ON (`Data`.`Data_client_id` = `client`.`client_id`)
WHERE `Data_status`.`Data_status_name` IN ('PAID') AND MONTH(`Data_result`.`result_ts`) = MONTH(CURRENT_DATE())
AND YEAR(`Data_result`.`result_ts`) = YEAR(CURRENT_DATE())
GROUP BY `client`.`client_group`
Result of said query:
Table
Try to distinct before run the 'sum' check whether this solve your problem
SELECT `client_group` , FORMAT(SUM(`Data_result_amount` ),2) as sum from (
SELECT DISTINCT `client`.`client_group` , `Data_result`.`Data_result_amount`
FROM
`qwer`.`Data_result`
INNER JOIN `qwer`.`Data`
ON (`Data_result`.`Data_result_lead` = `Data`.`Data_id`)
INNER JOIN `qwer`.`Data_status`
ON (`Data_result`.`Data_result_status_id` = `Data_status`.`Data_status_id`)
INNER JOIN `qwer`.`client`
ON (`Data`.`Data_client_id` = `client`.`client_id`)
WHERE `Data_status`.`Data_status_name` IN ('PAID') AND MONTH(`Data_result`.`result_ts`) = MONTH(CURRENT_DATE())
AND YEAR(`Data_result`.`result_ts`) = YEAR(CURRENT_DATE())
) T
GROUP BY `client_group`
you can check the query here http://sqlfiddle.com/#!9/36a3f8/6

SQL Join gives wrong results (creates duplicates)

I have a problem with my SQL join query. I have looked up other suggested answers and tried to apply it to my query, but it doesn't seem to be working.
I have this query:
SELECT SUM(p.quantity)
FROM stocktake_scans p
LEFT JOIN (
SELECT stocktake_area_id
FROM stocktake_areas
WHERE stocktake_id =8592 AND area_checked = 1
)d ON d.stocktake_area_id = p.stocktake_area_id
LEFT JOIN (
SELECT user_id
FROM stocktake_scan_edit
WHERE user_id =46521
)e ON e.user_id = p.stocktake_staff_id
WHERE p.stocktake_staff_id = 46521
And it gives me a result of 42, while I should get only 6. What is missing from the query?
I think you may have extra records with the same ID in your joined table that is where you are getting multiple rows returned from which is then calculating wrong in your sum, please try the below.
SELECT SUM(p.quantity) FROM stocktake_scans p LEFT JOIN ( SELECT distinct stocktake_area_id FROM stocktake_areas WHERE stocktake_id =8592 AND area_checked = 1 )d ON d.stocktake_area_id = p.stocktake_area_id LEFT JOIN ( SELECT distinct user_id FROM stocktake_scan_edit WHERE user_id =46521 )e ON e.user_id = p.stocktake_staff_id WHERE p.stocktake_staff_id = 46521

MySQL derived table with join

In the following query I'm having a problem when it comes to returning the right value for count2.
What I need is to get the number of rows from table2 which could easily be done by using a derived table t:
SELECT name,
(SELECT COUNT(*) FROM `table1`) AS count1,
(SELECT COUNT(*) FROM (
SELECT COUNT(*) FROM `table2` t2) WHERE t2.user = prf.user)
) t AS count2,
(SELECT SUM(a) FROM `table3`) AS count3
FROM `profiles` prf
WHERE 1=1
AND prf.user = 1
The problem is that the WHERE t2.user = prf.user statement fails as the prf table is outside the subquery's scope.
How can I achieve the above?
EDIT: I'm adding the actual query in case it's helpful for getting a better grasp:
SELECT PRF.BranchID, PRF.user_id, CONCAT_WS(" ",PRF.lastname,PRF.firstname) Synergatis,
( SELECT COUNT(*) FROM Actions A JOIN Requests R ON R.RequestID=A.RequestID WHERE A.ActionStatus = 302 AND A.UserOwner = PRF.user_id AND A.ActionDate BETWEEN '2015-06-01' AND '2015-06-10' ) AS energeies,
( SELECT COUNT(DISTINCT RPP.RequestID) FROM VW_Xartofylakio_Synergati VV JOIN Requests_Prop RPP ON RPP.PropertyID = VV.PropertyID JOIN Requests R ON R.RequestID = RPP.RequestID WHERE VV.CurrUsr = PRF.user_id AND R.ModifyTime BETWEEN '2015-06-01' AND '2015-06-10' ) AS zitiseis_eidikes,
( SELECT COUNT(DISTINCT(CustomerID)) FROM Demo_Orders_M WHERE DemoOrderStatus=253 AND USER=PRF.user_id AND DemoOrderDate BETWEEN '2015-06-01' AND '2015-06-10' ) AS endiaferomenoi,
( SELECT COUNT(*) AS cnt FROM Demo_Orders_M DOM JOIN Actions A ON DOM.DemoOrderID = A.DemoOrderID WHERE DOM.User = PRF.user_id AND DOM.DemoOrderStatus = 253 AND A.ActionDate BETWEEN '2015-06-01 14:56:19' AND '2015-06-30 14:56:19' GROUP BY DOM.CustomerID, DOM.User HAVING COUNT(*) > 1 ) AS anakykl_endiaf,
( SELECT COUNT(*) FROM Demo_Orders_M DOM WHERE DOM.`User`=PRF.user_id AND DemoOrderStatus = 253 AND DOM.DemoOrderDate BETWEEN '2015-06-01' AND '2015-06-10' ) AS epideixeis,
( SELECT COUNT(DISTINCT(DOD.PropertyID)) AS PropertyID FROM Demo_Orders_M DOM JOIN Demo_Orders_D DOD ON DOM.DemoOrderID = DOD.DemoOrderID JOIN Actions A ON DOD.DemoOrderID = A.DemoOrderID WHERE DOM.DemoOrderStatus = 253 AND DOM.User = PRF.user_id AND A.ActionDate BETWEEN '2015-06-01' AND '2015-06-10' ) AS monadika_akinita
FROM tbl_profiles PRF
WHERE 1=1
AND PRF.user_id IN (
SELECT a.user_id FROM tbl_profiles a WHERE a.user_id IN ('248','1159','486','183')
OR a.GroupID IN (SELECT b.GroupID FROM L_Groups b WHERE b.ManagerID IN ('248','1159','486','183'))
)
ORDER BY PRF.user_id
The subquery I'm referring to is the one that returns the result as anakykl_endiaf.
I suspect it is not because of prf table, it is because of t2 table... There are no restrictions to use outer alias in inner subqueries because there are such a thing like correlated subquery. Your problem is that you have the opposite case here: you are referring inner alias in outer query.
(SELECT COUNT(*)
FROM (SELECT COUNT(*) FROM `table2` t2) WHERE t2.user = prf.user)
Why are you selecting count twice here? You can change to this:
(SELECT COUNT(*)
FROM (SELECT COUNT(*) FROM `table2` t2 WHERE t2.user = prf.user))
or this:
(SELECT COUNT(*)
FROM `table2` t2 WHERE t2.user = prf.user)
A suggestion to try.
You have sub queries in the SELECT, and in this case they must each only return a single row. For some reason (which we can't really tell without test data) one of these is returning more than 1 row, hence failing.
As an interim step, change the query to join against the sub queries, which should make it more obvious when there are duplicates (and may also be quite a bit more efficient, depending on the data).
Something like this (not tested so probably a few typos):-
SELECT PRF.BranchID,
PRF.user_id,
CONCAT_WS(" ",PRF.lastname,PRF.firstname) Synergatis,
ar.energeies,
vrr.zitiseis_eidikes,
m.endiaferomenoi,
ae.anakykl_endiaf,
d.epideixeis,
ddd.monadika_akinita
FROM tbl_profiles PRF
LEFT OUTER JOIN
(
SELECT A.UserOwner AS DomUser, COUNT(*) AS energeies
FROM Actions A
JOIN Requests R ON R.RequestID=A.RequestID
WHERE A.ActionStatus = 302
AND A.ActionDate BETWEEN '2015-06-01' AND '2015-06-10'
GROUP BY A.UserOwner
) ar
ON ar.DomUser = PRF.user_id
LEFT OUTER JOIN
(
SELECT VV.CurrUsr AS DomUser, COUNT(DISTINCT RPP.RequestID) AS zitiseis_eidikes
FROM VW_Xartofylakio_Synergati VV
JOIN Requests_Prop RPP ON RPP.PropertyID = VV.PropertyID
JOIN Requests R ON R.RequestID = RPP.RequestID
WHERE R.ModifyTime BETWEEN '2015-06-01' AND '2015-06-10'
GROUP BY VV.DomUser
) vrr
ON vrr.DomUser = PRF.user_id
LEFT OUTER JOIN
(
SELECT `USER` AS DomUser, COUNT(DISTINCT(CustomerID)) AS endiaferomenoi
FROM Demo_Orders_M
WHERE DemoOrderStatus=253
AND DemoOrderDate BETWEEN '2015-06-01' AND '2015-06-10'
GROUP BY DomUser
) m
ON PRF.user_id = m.DomUser
LEFT OUTER JOIN
(
SELECT DOM.CustomerID, DOM.`User` AS DomUser, COUNT(*) AS anakykl_endiaf
FROM Demo_Orders_M DOM
JOIN Actions A ON DOM.DemoOrderID = A.DemoOrderID
WHERE DOM.DemoOrderStatus = 253
AND A.ActionDate BETWEEN '2015-06-01 14:56:19' AND '2015-06-30 14:56:19'
GROUP BY DOM.CustomerID, DOM.DomUser
HAVING COUNT(*) > 1
) ae
ON PRF.user_id = ae.DomUser
LEFT OUTER JOIN
(
SELECT DOM.`User` AS DomUser, COUNT(*) AS epideixeis
FROM Demo_Orders_M DOM
WHERE DemoOrderStatus = 253
AND DOM.DemoOrderDate BETWEEN '2015-06-01' AND '2015-06-10'
GROUP BY DOM.DomUser
) d
EDIT
If you just want a count of the number of customerID fields for a user in the anakykl_endiaf field then change it to doing a count of distinct customerIDs. Ie, for the above query I have done change it to:-
LEFT OUTER JOIN
(
SELECT DOM.`User` AS DomUser, COUNT(DISTINCT DOM.CustomerID) AS anakykl_endiaf
FROM Demo_Orders_M DOM
JOIN Actions A ON DOM.DemoOrderID = A.DemoOrderID
WHERE DOM.DemoOrderStatus = 253
AND A.ActionDate BETWEEN '2015-06-01 14:56:19' AND '2015-06-30 14:56:19'
GROUP BY DOM.DomUser
HAVING COUNT(*) > 1
) ae