How can I integrate a MySQL subquery - mysql

I have a MySQL subquery that I need to incorporate into my main query but i'm not sure how. My main query is shown below. I want to run that and as part of the same query run the subquery and get the result from that (which happens to be a sum) and then compare the result of the subquery in the main MySQL statement.
Main query
select * from employees_timesheet where
(sign_off_1 = 'Director' or sign_off_2 = 'Director' or sign_off_3 = 'Director')
and
(case when sign_off_1 <> 'Director' and sign_off_1_status = 'Compete'
then 1
else 0
end
+ case when sign_off_2 <> 'Director' and sign_off_2_status = 'Compete'
then 1
else 0
end
+ case when sign_off_3 <> 'Director' and sign_off_3_status = 'Compete'
then 1
else 0
end) = {{{$sign_offs_required}}}
Sub query
select
SUM(
case when employees_timesheet.sign_off_1 <> 'Director'
then 1
else 0
end
+ case when employees_timesheet.sign_off_2 <> 'Director'
then 1
else 0
end
+ case when employees_timesheet.sign_off_3 <> 'Director'
then 1
else 0
end
) as sign_offs_required
from employees_timesheet
Any help is mch appreciated.

I managed to get it to work using the following query:
select et.* from employees_timesheet et where
(et.sign_off_1 = 'Director' or et.sign_off_2 = 'Director' or et.sign_off_3 = 'Director')
and
(case when et.sign_off_1 <> 'Director' and et.sign_off_1_status = 'Approved'
then 1
else 0
end
+ case when et.sign_off_2 <> 'Director' and et.sign_off_2_status = 'Approved'
then 1
else 0
end
+ case when et.sign_off_3 <> 'Director' and et.sign_off_3_status = 'Approved'
then 1
else 0
end) =
(case when et.sign_off_1 <> 'Director'
then 1
else 0
end
+ case when et.sign_off_2 <> 'Director'
then 1
else 0
end
+ case when et.sign_off_3 <> 'Director'
then 1
else 0
end
)
group by et.id

Related

How to build a table which content becoming row

I would like to make a query on table as below:
enter image description here
b.sostatus required to become column title, and summarise the count of orderno
My SQL as below:
`
select
b.orderTime as orderDate,
sum( case when b.soStatus='00' then count(a.orderNo) else 0 end ) as Not_Allocated,
sum( case when b.soStatus='30' then count(a.orderNo) else 0 end ) as Partially_Allocated,
sum( case when b.soStatus='40' then count(a.orderNo) else 0 end ) as Allocated,
sum(case when b.soStatus='50' then count(a.orderNo) else 0 end ) as Partially_Picked ,
sum(case when b.soStatus='60' then count(a.orderNo) else 0 end ) as Picked,
sum(case when b.soStatus='63' then count(a.orderNo) else 0 end ) as Cartonized,
sum(case when b.soStatus='99' then count(a.orderNo) else 0 end ) as Closed,
case
when datediff(NOW(),b.orderTime) >=2 then '>=H-2'
when datediff(NOW(),b.orderTime) =1 then 'H-1'
when datediff(NOW(),b.orderTime) <1 then 'H' end as status
from DOC_ORDER_HEADER b
left join DOC_ORDER_DETAILS a
on
b.organizationId='ID_8COM'
and b.warehouseId='WHCPT01'
AND a.orderno = b.orderno
where b.organizationId='ID_8COM'
and b.warehouseId='WHCPT01'
`
However, it is popping error: Invalid use of group function
You don't need to use count() function on this requirement. sum(1) is enough to get the count based on your criteria.
select
b.orderTime as orderDate,
sum(case when b.soStatus='00' then 1 else 0 end) as Not_Allocated,
sum(case when b.soStatus='30' then 1 else 0 end) as Partially_Allocated,
sum(case when b.soStatus='40' then 1 else 0 end) as Allocated,
sum(case when b.soStatus='50' then 1 else 0 end) as Partially_Picked ,
sum(case when b.soStatus='60' then 1 else 0 end) as Picked,
sum(case when b.soStatus='63' then 1 else 0 end) as Cartonized,
sum(case when b.soStatus='99' then 1 else 0 end) as Closed,
case when datediff(NOW(),b.orderTime) >=2 then '>=H-2'
when datediff(NOW(),b.orderTime) = 1 then 'H-1'
when datediff(NOW(),b.orderTime) < 1 then 'H' end as status
from DOC_ORDER_HEADER b
left join DOC_ORDER_DETAILS a on b.organizationId='ID_8COM' and b.warehouseId='WHCPT01'
and a.orderno = b.orderno
where b.organizationId='ID_8COM'
and b.warehouseId='WHCPT01'
group by b.orderTime
You can also do this.
sum(b.soStatus='00')

I have a form content like this

I have a problem when it will create a view in phpmyadmin
like this # 1349 - SELECT Views contains subqueries in the FROM clause
my coding like this please help
SELECT b.ngr_tjuan, SUM (b.LFormal) AS LFormal, SUM (b.PFormal) AS PFormal, SUM (b.LFormal) + SUM (b.PFormal) AS SUMFormal,
SUM (b.LInformal) AS LInformal, SUM (b.PInformal) AS PInformal, SUM (b.LInformal) + SUM (b.PInformal) AS SUMInformal FROM
(SELECT a.ngr_tjuan,
(CASE WHEN a.sktor_pkrjaan = 'FORMAL' AND a.jk = 'L' THEN JJK ELSE 0 END) AS LFormal,
(CASE WHEN a.sktor_pkrjaan = 'FORMAL' AND a.jk = 'P' THEN JJK ELSE 0 END) AS PFormal,
(CASE WHEN a.sktor_pkrjaan = 'INFORMAL' AND a.jk = 'L' THEN JJK ELSE 0 END) AS LInformal,
(CASE WHEN a.sktor_pkrjaan = 'INFORMAL' AND a.jk = 'P' THEN JJK ELSE 0 END) US PInformal
FROM
(SELECT ngr_tjuan, COUNT (jk) AS JJK, sktor_pkrjaan, jk
FROM tbtki2
GROUP BY ngr_tjuan, sktor_pkrjaan, jk) a
WHERE a.JJK> 0) b
GROUP BY b.ngr_tjuan

Mysql query optimization takes more than 30 sec

Hi friends can any one please help me to optimize this query ,it takes more than 30 sec.
any suggestion is warmly welcome.
Query :
SELECT
CONCAT(CCD.CONTACT_FIRST_NAME, ' ', CCD.CONTACT_LAST_NAME) AS NAME,
A.EMAIL_IDS,
CCD.UNSUBSCRIBE,
IFNULL(CSL.LOG_DATE, '') AS LOG_DATE,
CSL.IP_ADDRESS,
IF(CSL.BROWSER IS NULL, '', CSL.BROWSER) AS BROWSER,
(CASE
WHEN (UNSUBSCRIBE = 0 OR UNSUBSCRIBE IS NULL) THEN 'Opted In'
ELSE (CASE
WHEN (UNSUBSCRIBE = 1) THEN 'Opted Out'
ELSE (CASE
WHEN
((UNSUBSCRIBE = 2 OR UNSUBSCRIBE = 3)
AND CCD.CONTACT_ID NOT IN (SELECT
CONTACT_ID
FROM
CM_SUBSCRIPTION_MAIL_DATA
WHERE
IS_MAIL_SENT = 'Y'))
THEN
'Opt-In Request not Sent'
ELSE 'Opt-In Pending'
END)
END)
END) AS CURR_SUB,
(CASE
WHEN (SUBSCRIBE_FROM = 0) THEN 'Opted In'
ELSE (CASE
WHEN (SUBSCRIBE_FROM = 1) THEN 'Opted Out'
ELSE (CASE
WHEN (SUBSCRIBE_FROM = 2 OR SUBSCRIBE_FROM = 3) THEN 'Opt-In Pending'
ELSE ''
END)
END)
END) AS SUB_FROM,
SUBSCRIBE_FROM,
(CASE
WHEN (SUBSCRIBE_TO = 0) THEN 'Opted In'
ELSE (CASE
WHEN (SUBSCRIBE_TO = 1) THEN 'Opted Out'
ELSE (CASE
WHEN (SUBSCRIBE_TO = 2 OR SUBSCRIBE_TO = 3) THEN 'Opt-In Pending'
ELSE ''
END)
END)
END) AS SUB_TO,
SUBSCRIBE_TO
FROM
CM_CONTACT_DETAILS CCD
LEFT JOIN
ADDRESS A ON CCD.CONTACT_ID = A.FOREIGN_ID
LEFT JOIN
CM_SUBSCRIPTION_LOGS CSL ON CSL.CONTACT_ID = CCD.CONTACT_ID
WHERE
1 = 1
GROUP BY CSL.LOG_DATE , CCD.CONTACT_ID
ORDER BY NAME DESC , LOG_DATE DESC
LIMIT 0 , 20
Your case/when can be simplified, but I believe the killer of your query was the correlated NOT IN SELECT clause for your Opt-in request not sent.
I've change your query to do a left-join to your mailing table based on the contact AND the mailed status of "Y". So this simplifies your case to only have to check for IS NULL of the mailing table contact ID.
You can't do too much on performance since your Group by is by columns from different tables that won't take advantage of any index optimization, then all that ordered by the name makes it more of an issue... but the correlated subquery per the field being executed every time to a left-join SHOULD help.
SELECT
CONCAT(CCD.CONTACT_FIRST_NAME, ' ', CCD.CONTACT_LAST_NAME) AS NAME,
A.EMAIL_IDS,
CCD.UNSUBSCRIBE,
IFNULL(CSL.LOG_DATE, '') AS LOG_DATE,
CSL.IP_ADDRESS,
IF(CSL.BROWSER IS NULL, '', CSL.BROWSER) AS BROWSER,
CASE WHEN UNSUBSCRIBE = 0 OR UNSUBSCRIBE IS NULL THEN 'Opted In'
WHEN UNSUBSCRIBE = 1 THEN 'Opted Out'
WHEN UNSUBSCRIBE IN (2,3) AND SMD.CONTACT_ID IS NULL THEN 'Opt-In Request not Sent'
ELSE 'Opt-In Pending' END AS CURR_SUB,
CASE WHEN SUBSCRIBE_FROM = 0 THEN 'Opted In'
WHEN SUBSCRIBE_FROM = 1 THEN 'Opted Out'
WHEN SUBSCRIBE_FROM = 2 OR SUBSCRIBE_FROM = 3 THEN 'Opt-In Pending'
ELSE '' END AS SUB_FROM,
SUBSCRIBE_FROM,
CASE WHEN SUBSCRIBE_TO = 0 THEN 'Opted In'
WHEN SUBSCRIBE_TO = 1 THEN 'Opted Out'
WHEN SUBSCRIBE_TO = 2 OR SUBSCRIBE_TO = 3 THEN 'Opt-In Pending'
ELSE '' END AS SUB_TO,
SUBSCRIBE_TO
FROM
CM_CONTACT_DETAILS CCD
LEFT JOIN ADDRESS A
ON CCD.CONTACT_ID = A.FOREIGN_ID
LEFT JOIN CM_SUBSCRIPTION_LOGS CSL
ON CSL.CONTACT_ID = CCD.CONTACT_ID
LEFT JOIN CM_SUBSCRIPTION_MAIL_DATA SMD
ON CCD.CONTACT_ID = SMD.CONTACT_ID
AND IS_MAIL_SENT = 'Y'
WHERE
1 = 1
GROUP BY
CSL.LOG_DATE,
CCD.CONTACT_ID
ORDER BY
NAME DESC,
LOG_DATE DESC
LIMIT
0, 20

How to sort data with a case statement - using MySQL?

I have a query but I want to order the data as the following:
status (so I have the records with status = 1 on the top and status 2 at the bottom)
if the records have status = 1 then order them as the following
a) CASE WHEN i.assigned_to = '.USER_ID.' THEN 0 ELSE 1 END
b) CASE WHEN (i.approved_by > 0 OR i.approved_on IS NOT NULL) THEN 0 ELSE 1 END
c) i.priority DESC
d) i.created_on ASC
if the records have status = 2 then order the records by completed_on DESC
This is my current syntax but I can't figure out how to split the order
ORDER BY
i.status ASC,
CASE WHEN i.assigned_to = '.USER_ID.' THEN 0 ELSE 1 END,
CASE WHEN (i.approved_by > 0 OR i.approved_on IS NOT NULL) THEN 0 ELSE 1 END,
i.priority DESC,
i.created_on ASC
My query currently order all the records by
a) CASE WHEN i.assigned_to = '.USER_ID.' THEN 0 ELSE 1 END
b) (CASE WHEN (i.approved_by > 0 OR i.approved_on IS NOT NULL) THEN 0 ELSE 1 END)
c) i.priority DESC
d) i.created_on ASC
and I want it to order by those only if the status = 1 otherwise order by completed_on DESC
Try:
ORDER BY
i.status ASC,
CASE WHEN i.assigned_to = '.USER_ID.' and i.status = 1 THEN 0 ELSE 1 END,
CASE WHEN (i.approved_by > 0 OR i.approved_on IS NOT NULL) and i.status = 1
THEN 0 ELSE 1 END,
CASE WHEN i.status = 1 THEN i.priority END DESC,
CASE WHEN i.status = 1 THEN i.created_on END ASC,
CASE WHEN i.status = 2 THEN i.completed_on END DESC

Case When with AND?

I want to use Case When with AND condition and it is not calculating the sum properly.
For example:
SELECT DATE(`SubmitDate`),
SUM(CASE status WHEN 'New' AND `Type` = 'consumer' THEN 1 ELSE 0 END) as new_consumer,
SUM(CASE status WHEN 'New' AND `Type` = 'business' THEN 1 ELSE 0 END) as new_business
FROM report
WHERE `source` = 'net'
group by DATE(`SubmitDate`) Order by `SubmitDate` DESC
You need to use CASE WHEN [Condition] THEN... rather than a simple case expression:
SELECT DATE(`SubmitDate`),
SUM(CASE WHEN status = 'New' AND `Type` = 'consumer' THEN 1 ELSE 0 END) as new_consumer,
SUM(CASE WHEN status = 'New' AND `Type` = 'business' THEN 1 ELSE 0 END) as new_business
FROM report
WHERE `source` = 'net'
group by DATE(`SubmitDate`) Order by `SubmitDate` DESC
You should write
CASE WHEN status='New' AND `Type` = 'consumer' THEN 1 ELSE 0 END
Check the syntax of CASE WHEN