How to join with having in mysql? - 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;

Related

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

How to join two queries in one and get results in a single query?

SELECT SUM(commission) as regularincome FROM `tbl_member_commission` where mem_id=2 AND MONTH(cdate) = MONTH(CURRENT_DATE())
SELECT SUM(commission) as crowdfund FROM `tbl_member_comm_month` where mem_id=2 AND MONTH(cdate) = MONTH(CURRENT_DATE())
note:- both of tables have these same column names : commission, mem_id, cdate
If this is the only record in each subquery, you can use CROSS JOIN:
select a.regularincome, b.crowdfund
FROM
(SELECT SUM(commission) as regularincome FROM `tbl_member_commission` where mem_id=2 AND MONTH(cdate) = MONTH(CURRENT_DATE())) as a
cross join
(SELECT SUM(commission) as crowdfund FROM `tbl_member_comm_month` where mem_id=2 AND MONTH(cdate) = MONTH(CURRENT_DATE())) as b

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

Sql trouble with coalesce() not working propely

i have a query and i'm having trouble to change the name of the last row of columb name to 'TOTAL'. The result gives me the same name of the row above the last row.
Here's my query:
SELECT COALESCE(ticket_types.name,'TOTAL') AS name,
COUNT(1) AS quantity
FROM tr_logs
LEFT JOIN tickets ON tr_logs.value = tickets.id
LEFT JOIN ticket_types ON tickets.ticket_type_id = ticket_types.id
LEFT JOIN transactions ON tr_logs.transaction_id = transactions.id
LEFT JOIN tr_fields_data AS tfd_shipping ON tfd_shipping.transaction_id = transactions.id
WHERE type = 'ADDITEM'
AND transactions.event_id = '46'
AND DATE(tr_logs.created_date)
BETWEEN '2017-03-26' AND '2017-05-24'
AND tfd_shipping.data IN ('0','570','571','771')
AND name IS NOT NULL
GROUP BY ticket_types.id WITH ROLLUP
The result looks like this:
name quantity
premium 56
outlaw 6
outlaw 62
Last row name from rollup is not null.... I need it to be TOTAL and not outlaw
Thanks
You haven't changed the name to TOTAL at all: you've changed the name of the column to name, and you've told it to replace any null values with TOTAL.
If you want to change the name of ticket_types.name to total, you just want
SELECT ticket_types.name AS total ...
(But it would be weird to rename something called name to total, so perhaps you need to clarify your requirements a little.)
This may or not be related to your observed problem, but the WHERE and GROUP BY clauses turn all the outer joins into inner joins. You should simplify the query to:
SELECT COALESCE(tt.name, 'TOTAL') AS name, COUNT(1) AS quantity
FROM tr_logs l JOIN
tickets
ON l.value = t.id JOIN
ticket_types tt
ON t.ticket_type_id = tt.id JOIN
transactions tr
ON l.transaction_id = tr.id JOIN
tr_fields_data fd
ON fd.transaction_id = tr.id
WHERE type = 'ADDITEM' AND
tr.event_id = '46' AND
DATE(l.created_date) BETWEEN '2017-03-26' AND '2017-05-24' AND
fd.data IN ('0', '570', '571', '771') AND
tt.name IS NOT NULL
GROUP BY tt.id WITH ROLLUP
Thanks to Gordon Linoff I have figure out my problem.
The name of the last row was never null beacause i GROUP BY with a different attribute.
Here's the solution.
SELECT COALESCE(tckn,'TOTAL') AS name, quantity FROM
(SELECT tt.name AS tckn, COUNT(1) AS quantity
FROM tr_logs AS l
LEFT JOIN tickets AS t ON l.value = t.id
LEFT JOIN ticket_types AS tt ON t.ticket_type_id = tt.id
LEFT JOIN transactions AS tr ON l.transaction_id = tr.id
LEFT JOIN tr_fields_data AS tfd ON tfd.transaction_id = tr.id
WHERE type = 'ADDITEM'
AND tr.event_id = '46'
AND DATE(l.created_date)
BETWEEN '2017-03-26' AND '2017-05-24'
AND tfd.data IN ('0','570','571','771')
GROUP BY tckn WITH ROLLUP) as sum;

Count invitation response against events and response codes

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