Using two different measures in a having statement - mysql

I am including the code I am trying to use. What I want is to get a count of encounter id's for each doctor. I want to capture patients who have had at least 2 visits or who have had one preventive visit. I don't know how to make this work using the having statement. thanks for any assistance.
SELECT e.doctorID, COUNT(DISTINCT e.encounterID) AS VisitCount
FROM enc e
JOIN users u ON e.patientID = u.uid
Left JOIN diagnosis d ON e.encounterID = d.encounterID
LEFT JOIN items it ON d.itemID = it.itemID
LEFT JOIN itemdetail id ON it.itemID = id.itemID
WHERE e.encType = 1 AND e.status = 'CHK' AND e.deleteFlag = 0 AND
e.date BETWEEN DATE_ADD((LAST_DAY(DATE_ADD(CURDATE(),INTERVAL -2 MONTH))), INTERVAL 1 DAY) AND LAST_DAY(DATE_ADD(CURDATE(),INTERVAL -1 MONTH))
AND FLOOR(DATEDIFF(NOW(),u.ptdob)/365.25) >= 18 AND e.doctorID = e.resourceID
GROUP BY e.doctorID, id.value
HAVING
COUNT(e.patientid)>=2 OR
id.value in ('Z00.00', 'Z00.01')

You dont need to include id.value in grp by clause. Try to give valid condition in having clause with id.value
select e.doctorID,
COUNT(distinct e.encounterID) as VisitCount from enc e join users u on e.patientID = u.uid
left join diagnosis d on e.encounterID = d.encounterID left join items it on
d.itemID = it.itemID left join itemdetail id on
it.itemID = id.itemID where e.encType = 1 and e.status ='CHK' and e.deleteFlag = 0 and
e.date between DATE_ADD((LAST_DAY(DATE_ADD(CURDATE(), INTERVAL - 2 MONTH))), INTERVAL 1 DAY)
and LAST_DAY(DATE_ADD(CURDATE(), INTERVAL - 1 MONTH))
and
FLOOR(DATEDIFF(NOW(), u.ptdob) / 365.25) >= 18
and e.doctorID = e.resourceID group by e.doctorID
having COUNT(e.patientid) >= 2
or sum(case when id.value in ('Z00.00','Z00.01') then 1
else 0 end)>=1

Related

mysql select if datediff is greater than

I would like to query users from lat 3 years only if the time diffrence of date_start and date_end is greater than 3 months. I have tried a lot of things but nothing works. This is the statment i made until now :
SELECT accounts.account_id, accounts.name, accounts.active_club_id,
accounts.phone, MIN(shifts_accounts.date_start) as 'datestart', MAX(shifts_accounts.date_end) as 'dateend'
FROM `shifts_accounts`
JOIN accounts ON shifts_accounts.account_id = accounts.account_id
JOIN accounts_groups ON accounts.account_id = accounts_groups.account_id
WHERE accounts_groups.group_id = 7
AND DATEDIFF('dateend', 'datestart') > 90
AND accounts.active_club_id != 1
AND shifts_accounts.date_start > '2014-11-28'
AND shifts_accounts.date_start < '2017-11-28' GROUP BY accounts.account_id
The following is an example of a valid query. I don't think there's enough information to say whether it's what you want or not...
SELECT a.account_id
, a.name
, a.active_club_id
, a.phone
, MIN(sa.date_start) datestart
, MAX(sa.date_end) dateend
FROM shifts_accounts sa
JOIN accounts a
ON a.account_id = sa.account_id
JOIN accounts_groups ag
ON ag.account_id = a.account_id
WHERE ag.group_id = 7
AND a.active_club_id != 1
AND sa.date_start BETWEEN '2014-11-28' AND '2017-11-28'
GROUP
BY a.account_id
HAVING DATEDIFF(dateend, datestart) > 90;
For further help, see: Why should I provide an MCVE for what seems to me to be a very simple SQL query?
Try with this,
SELECT accounts.account_id, accounts.name, accounts.active_club_id,
accounts.phone, MIN(shifts_accounts.date_start) as 'datestart', MAX(shifts_accounts.date_end) as 'dateend'
FROM `shifts_accounts`
JOIN accounts ON shifts_accounts.account_id = accounts.account_id
JOIN accounts_groups ON accounts.account_id = accounts_groups.account_id
WHERE accounts_groups.group_id = 7
AND DATEDIFF('dateend', 'datestart') > 90
AND accounts.active_club_id != 1
AND shifts_accounts.date_start < DATE_SUB(NOW(),INTERVAL 3 YEAR) GROUP BY accounts.account_id

Return ROW COUNT from stored procedure in MySQL (MariaDB)

How can I return the row count from the query in this stored procedure? I have been trying to implement solutions found on other stack overflow posts that are similar but each result in the output being the columns with the count for each individual record. (ie, one column will output 1,1,1,1,1 for every row...)
CREATE PROCEDURE stored_proc ()
BEGIN
SET #start_date = LAST_DAY(NOW() - INTERVAL 2 MONTH) + INTERVAL 1 DAY;
SET #end_date = LAST_DAY(NOW() - INTERVAL 1 MONTH);
SELECT users.*, count(DISTINCT mr_rev.id) AS prev_reg
FROM users
INNER JOIN gr_user_group
ON gr_user_group.user_id = wp_users.ID
AND gr_user_group.group_id != 22
AND gr_user_group.group_id = 5
INNER JOIN usermeta ON users.ID = usermeta.user_id
INNER JOIN mr_rev
ON users.ID = mr_rev.users_id AND mr_rev.mr_rev_types_id = 2
INNER JOIN mr_rev mrr
ON users.ID = mrr.users_id
AND mrr.mr_rev_types_id = 2
AND mrr.created_on >= #start_date
AND mrr.created_on <= #end_date
INNER JOIN mr_revs_meta
ON mr_rev.id = mr_revs_meta.mr_rev_id
AND mr_revs_meta.meta_value > #end_date
AND mr_revs_meta.created_at < #end_date
WHERE users.ID NOT IN ('101', '102')
GROUP BY users.ID
HAVING prev_reg > 15;
END;
Is there an efficient way to return the total row count?
EDIT: Return count in Stored Procedure one of the posts I unsuccessfully implemented.
How about wrapping the query in an another select:
SELECT COUNT(*) FROM
(SELECT users.*, count(DISTINCT mr_rev.id) AS prev_reg
FROM users
INNER JOIN gr_user_group
ON gr_user_group.user_id = wp_users.ID
AND gr_user_group.group_id != 22
AND gr_user_group.group_id = 5
INNER JOIN usermeta ON users.ID = usermeta.user_id
INNER JOIN mr_rev
ON users.ID = mr_rev.users_id AND mr_rev.mr_rev_types_id = 2
INNER JOIN mr_rev mrr
ON users.ID = mrr.users_id
AND mrr.mr_rev_types_id = 2
AND mrr.created_on >= #start_date
AND mrr.created_on <= #end_date
INNER JOIN mr_revs_meta
ON mr_rev.id = mr_revs_meta.mr_rev_id
AND mr_revs_meta.meta_value > #end_date
AND mr_revs_meta.created_at < #end_date
WHERE users.ID NOT IN ('101', '102')
GROUP BY users.ID
HAVING prev_reg > 15 ) a;

Sum does'nt work for multiply

SELECT Sum((pvc.cpt_amount) * (pvc.unit)) AS billed_amount,
pvc.cpt_amount,
pvc.unit
FROM payment AS pay
LEFT JOIN patient_insurances AS pi
ON pay.who_paid = pi.id
LEFT JOIN patient_visit_cpt AS pvc
ON (
pay.encounter_id = pvc.id
AND pay.claim_id = pvc.claim_id )
LEFT JOIN patient_visit AS pv
ON pvc.visit_id = pv.id
WHERE
and pi.insurance_id = 761
AND pay.created_at <= '2016-04-01 23:00:00'
AND pay.created_at >= '2016-03-31 00:00:00'
GROUP BY pay.check_number,
pv.attending_provider_id
for unit = 1 and cpt_amount = 145, but output comes like
mulitplied with 4. like 1 * 145 = 580.. please any one give solution
Your Group By might be wrong.
Also remove keyword AND after the WHERE Clause
Try below query
SELECT Sum((pvc.cpt_amount) * (pvc.unit)) AS billed_amount,
pvc.cpt_amount,pvc.unit
FROM payment AS pay
LEFT JOIN patient_insurances AS pi ON pay.who_paid = pi.id
LEFT JOIN patient_visit_cpt AS pvc ON(pay.encounter_id = pvc.id AND pay.claim_id = pvc.claim_id)
LEFT JOIN patient_visit AS pv ON pvc.visit_id = pv.id
WHERE pi.insurance_id = 761 AND pay.created_at <= '2016-04-01 23:00:00'
AND pay.created_at >= '2016-03-31 00:00:00'
GROUP BY pvc.cpt_amount,pvc.unit

Select in Select MySQL

I have two queries, i'd like if is possible execute in only one query as a Select in Select.
The first one:
SELECT
users.id
FROM users
LEFT JOIN users_date ON users_date.user = users.id
LEFT JOIN users_varchar ON users_varchar.user = users.id
WHERE
abilitato = 1
AND users_date.key = 'birthday'
AND users_varchar.key = 'nation'
AND users_varchar.value = 'US'
AND (users.reg_date >= '2013-05-31' AND users.reg_date <= '2013-05-31')
AND (floor(DATEDIFF(NOW(), users_date.value) / 365) >= 19 AND floor(DATEDIFF(NOW(), users_date.value) / 365) <= 19)
it retrieve a list of user id (filtered by Age, Nation or Date of registration)
the second one:
SELECT count(`matches`.`id`) FROM `matches` WHERE (`matches`.`status_home` = 3 AND `matches`.`status_guest` = 3) AND (`matches`.`team_home` = 13 OR `matches`.`team_guest` = 13)
i need perform the second select for every ID retrieved by the one's.
for every perform i must replace the value 13 with the id retrieved.
it is possible perform all in a single query with a select in select?
thanks advance for your help
Try this sql.
SELECT count(`matches`.`id`)
FROM `matches` m
INNER JOIN ( SELECT users.id as id
FROM users
LEFT JOIN users_date ON users_date.user = users.id
LEFT JOIN users_varchar ON users_varchar.user = users.id
WHERE abilitato = 1
AND users_date.key = 'birthday'
AND users_varchar.key = 'nation'
AND users_varchar.value = 'US'
AND (users.reg_date >= '2013-05-31' AND users.reg_date <= '2013-05-31')
AND (floor(DATEDIFF(NOW(), users_date.value) / 365) >= 19 AND floor(DATEDIFF(NOW(), users_date.value) / 365) <= 19)) t
on t.id=m.team_guest
WHERE (`matches`.`status_home` = 3 AND `matches`.`status_guest` = 3)
AND (`matches`.`team_home` = 13 OR `matches`.`team_guest` = t.id)
GROUP BY t.id
You can express what you want to do as an explicit join. But the question asks for a select within a select. For that, you need a correlated subquery. Here is the final query:
select users.id,
(SELECT count(`matches`.`id`)
FROM `matches`
WHERE (`matches`.`status_home` = 3 AND `matches`.`status_guest` = 3) AND
(`matches`.`team_home` = user.id OR `matches`.`team_guest` = users.id)
) as cnt
FROM users LEFT JOIN
users_date
ON users_date.user = users.id LEFT JOIN
users_varchar
ON users_varchar.user = users.id
WHERE abilitato = 1 AND users_date.key = 'birthday' AND
users_varchar.key = 'nation' AND users_varchar.value = 'US' AND
(users.reg_date >= '2013-05-31' AND users.reg_date <= '2013-05-31') AND
(floor(DATEDIFF(NOW(), users_date.value) / 365) >= 19 AND
floor(DATEDIFF(NOW(), users_date.value) / 365) <= 19
)
(The formatting helps me understand the query better.)
Doing this without a correlated subquery is a bit challenging because of the or in the matching condition.

mysql date_add 2 times in procedure

i want to use Date_add 2 times in a procedure, but it returns 0 rows (while it should return rows)
Here is the procedure
select av.*, ap.*,c.* from tbl_available av
left join tbl_appointment ap on av.avHours = ap.appointmenttime
and ap.calendarid = kalenderId
and ap.appointmentdate = DATE_ADD(dag, INTERVAL 6 DAY)
left join tbl_client c on ap.clientid = c.clientid
where av.avCalendarId = KalenderId
and av.avDays = DayOfweek(DATE_ADD(dag, INTERVAL 6 DAY))
order by avHours;
it works without the date_add
thanks in advance!
//edit
What i have now:
select av.*, ap.*,c.*, ab.absentid from tbl_available av
left join tbl_appointment ap on av.avHours = ap.appointmenttime
and ap.calendarid = kalenderId
and ap.appointmentdate BETWEEN dag AND DATE_ADD(dag, INTERVAL 6 DAY)
and (av.avDays = DayOfweek(ap.appointmentdate) OR ap.appointmentdate IS NULL)
left join tbl_client c on ap.clientid = c.clientid
left join tbl_absent ab on av.avHours = ab.ababsent
and ab.abHoliday = dag
and ab.abCalendarID = kalenderId
where av.avCalendarId = kalenderId
order by avDays,avHours;
But the ab.absentid is not fetched, why is that? :(
I'm not sure exactly what you want, but for the whole week, try something like:
select av.*, ap.*,c.* from tbl_available av
left join tbl_appointment ap on av.avHours = ap.appointmenttime
and ap.calendarid = kalenderId
and ap.appointmentdate BETWEEN dag AND DATE_ADD(dag, INTERVAL 6 DAY)
and (av.avDays = DayOfweek(ap.appointmentdate) OR ap.appointmentdate IS NULL)
left join tbl_client c on ap.clientid = c.clientid
where av.avCalendarId = KalenderId
order by avHours;
I'm using BETWEEN to specify the date range for ap.appointmentdate. The av.avDays is changed to either correlate to ap.appointmentdate or also show rows with no appointment (assumed this behavior because you have a LEFT JOIN on tbl_appointment). I have left off DayOfweek(dag) ... because you are looking at a whole week so this is redundant.