How to calculate weekends of time range using MySQL - mysql

I need to calculate weekends of time range using MySQL.
This is what I have so far(about calculate working days but i want to calculate weekends):
select
(floor(days / 7)* 5
+ days%7
- case
when 6 between wd and wd + days%7 - 1 then 1
else 0
end
- case
when 7 between wd and wd + days%7 - 1 then 1
else 0
end) as result
from
(
select
abs(datediff('2022-05-15', '2022-05-13')) + 1 as days,
weekday('2022-05-13') + 1 as wd ) as a;
Hope I explained well...
Thanks.

select
(floor(days / 7)* 2
+ case
when 6 between wd and wd + days%7 - 1 then 1
else 0
end
+ case
when 7 between wd and wd + days%7 - 1 then 1
else 0
end) as result
from ( select
abs(datediff('2022-05-15', '2022-05-13')) + 1 as days,
weekday('2022-05-13') + 1 as wd ) as a;
Maybe this will work. Have a try.

Related

Select with count

So.. here is the thing.. Im trying to get a report based on this table on Mysql.
Table have these columns
statusvalue submitdate employeeNumber
2 2016-11-17 17:49:05 2
1 2016-11-17 17:49:11 4
3 2016-11-17 17:49:16 4
4 2016-11-17 17:50:58 2
5 2016-11-17 17:51:07 5
Status 0 = Pending
1= Started
2=inprogress
3= cancelled
4= terminated
5=unknown
now i need to select data as below
date day pending started inprogress cancelled terminated total
2017-04-17 Monday 0 1 4 0 1 6
2017-04-16 Sunday 0 1 4 0 1 6
so far i can get the date and the day
select date(submitdate) as subdate, case weekday(date(submitdate))
WHEN 0 then 'PENDING'
WHEN 1 then 'STARTED'
WHEN 2 then 'INPROGRESS'
WHEN 3 then 'CANCELLED'
WHEN 4 then 'TERMINATED'
WHEN 5 then 'UNKNOWN' END as submitdate
from tb_status t1 where employeenumber=15 group by subdate order by subdate ;
however not quite sure how to do a count based on status.. any help would be greatly appreciated.
You just need a basic pivot query here. Aggregate over the submission date, and then tally the various types of status as you go along.
SELECT
DATE(submitdate) AS subdate,
WEEKDAY(submitdate) AS day,
SUM(CASE WHEN WEEKDAY(DATE(submitdate)) = 0 THEN 1 END) AS PENDING,
SUM(CASE WHEN WEEKDAY(DATE(submitdate)) = 1 THEN 1 END) AS STARTED,
SUM(CASE WHEN WEEKDAY(DATE(submitdate)) = 2 THEN 1 END) AS INPROGRESS,
SUM(CASE WHEN WEEKDAY(DATE(submitdate)) = 3 THEN 1 END) AS CANCELLED,
SUM(CASE WHEN WEEKDAY(DATE(submitdate)) = 4 THEN 1 END) AS TERMINATED,
SUM(CASE WHEN WEEKDAY(DATE(submitdate)) = 5 THEN 1 END) AS UNKNOWN
FROM tb_sattus t1
WHERE employeenumber = 15
GROUP BY DATE(submitdate)
ORDER BY subdate
Note that your current query is not correct, because you are selecting string literals based on the status. Instead, in my query the various status types appear as column names, with the counts you want instead being selected.
Give this a try:
SELECT
`submitDate` as `date`,
DATE_FORMAT(`submitDate`,'%a') as `day`,
SUM(if(`statusvalue` = 0,1,0)) as `pending`,
SUM(if(`statusvalue` = 1,1,0)) as `started`,
SUM(if(`statusvalue` = 2,1,0)) as `inprogress`,
SUM(if(`statusvalue` = 3,1,0)) as `cancelled`,
SUM(if(`statusvalue` = 4,1,0)) as `terminated`,
SUM(if(`statusvalue` = 5,1,0)) as `unknown`,
SUM(if(NOT `statusvalue` IN (0,1,2,3,4,5),1,0)) as `invalid`,
COUNT(`statusvalue`) as `total`
FROM `tbstatus`
GROUP BY `submitDate`
ORDER BY `submitDate`;

MySQL SUM with CASE choose latest record by date

I've got the SUM CASE statements working properly. The issue is that I have multiple records with similar criteria, so I'd like to select the latest record by date.
SELECT
SUM(CASE WHEN planning like 'Rotation%' THEN 1 ELSE 0 END +
CASE WHEN assessmentanddata like 'Collects%' THEN 1 else 0 END +
CASE WHEN path like 'Same%' THEN 1 else 0 END +
CASE WHEN place like 'Move%' THEN 1 else 0 END +
CASE WHEN pace like 'Timer%' THEN 1 else 0 END +
CASE WHEN classroommanagement like 'Restating%' THEN 1 else 0 END +
CASE WHEN teacherrole like 'Mini%' THEN 1 else 0 END +
CASE WHEN studentengagement like 'Follow%' THEN 1 else 0 END +
CASE WHEN studentcollaboration like 'Collects%' THEN 1 else 0 END +
CASE WHEN technology like 'Technology%' THEN 1 else 0 END) AS p1
from ruberic where schoolId = 1
A sample from the table will be these 3 columns of DATE, SCHOOLID, and TEACHERID:
2016-12-05 1 1 -> This record will be fine
2016-12-05 1 4 -> Select only this when compared with the record below
2016-12-05 1 4
Building on what I see (I don't see the field name for date so assumed date)
This uses a correlates subquery and an exists statement to identify the max(date) for each teacherID and school and then limits the main dataset by this subset through the coloration.
SELECT
SUM(CASE WHEN planning like 'Rotation%' THEN 1 ELSE 0 END +
CASE WHEN assessmentanddata like 'Collects%' THEN 1 else 0 END +
CASE WHEN path like 'Same%' THEN 1 else 0 END +
CASE WHEN place like 'Move%' THEN 1 else 0 END +
CASE WHEN pace like 'Timer%' THEN 1 else 0 END +
CASE WHEN classroommanagement like 'Restating%' THEN 1 else 0 END +
CASE WHEN teacherrole like 'Mini%' THEN 1 else 0 END +
CASE WHEN studentengagement like 'Follow%' THEN 1 else 0 END +
CASE WHEN studentcollaboration like 'Collects%' THEN 1 else 0 END +
CASE WHEN technology like 'Technology%' THEN 1 else 0 END) AS p1
FROM
ruberic R1
WHERE
schoolId = 1
AND EXISTS (SELECT Null
FROM ruberic r2
WHERE R2.SchoolID = R1.SchoolID
AND R2.TeacherID = R1.TeacherID
GROUP BY SchoolID, TeacherID
HAVING R1.Date = MAX(R2.Date) )

MYSQL: Get average of fields in case where value is not a certain value

Say I have a table with 5 columns,
A, B, C, D, E
that are integers. I want to get the average of all of the fields in that case, that are not 3.
So, on some sample data:
A, B, C, D, E DESIRED RESULT
-------------
1, 1, 4, 4, 3 -> 2.5 (NOT 2.6)
1, 2, 3, 3, 3 -> 1.5 (NOT 2.4)
EDIT: I found a solution.
(
(
IF(A!=3,A,0)
+IF(B!=3,B,0)
+IF(C!=3,C,0)
+IF(D!=3,D,0)
+IF(E!=3,E,0)
)
/
(
IF(A!=3,1,0)
+IF(B!=3,1,0)
+IF(C!=3,1,0)
+IF(D!=3,1,0)
+IF(E!=3,1,0)
)
) as VALUE
Try that:
select avg(CASE WHEN A = 3 then 0 else A end +
CASE WHEN B = 3 then 0 else B end +
CASE WHEN C = 3 then 0 else C end +
CASE WHEN D = 3 then 0 else D end +
CASE WHEN E = 3 then 0 else E end)/
(CASE WHEN A = 3 then 0 else 1 end +
CASE WHEN B = 3 then 0 else 1 end +
CASE WHEN C = 3 then 0 else 1 end +
CASE WHEN D = 3 then 0 else 1 end +
CASE WHEN E = 3 then 0 else 1 end) as av from table1
group by A,B,C,D,E
DEMO HERE

MYSQL select rows when criteria in at least x colums is met?

Another MYSQL question where I could not find an answer:
I have this table and I want to to get all ID's which have SN>7 AND reps > 4 and where in columns 1-6 a certain criteria is met at least x times.
For example where at least 3 cells in columns col1-col6 have a value > 1.
The first part is easy (SELECT * FROM table WHERE SN > 7 AND reps > 4....) but I can't figure out second part.
Thanks!
ID SN reps col1 col2 col3 col4 col5 col6
A 12 3 0.6 1 3 -2 1 3
B 6 5 3.2 1.1 -3.3 3 0 0
C 300 6 1.3 -0.4 0 0.6 -0.5 -3.3
Try:
SELECT * FROM table
WHERE SN > 7 AND reps > 4 and
(case when `1` > 1 then 1 else 0 end +
case when `2` > 1 then 1 else 0 end +
case when `3` > 1 then 1 else 0 end +
case when `4` > 1 then 1 else 0 end +
case when `5` > 1 then 1 else 0 end +
case when `6` > 1 then 1 else 0 end) >= 3
select * from table where sn> 7 and reps > 4 and
(((`1` > 1) + (`2` > 1 ) + (`3` > 1) + (`4` > 1) + (`5` >1 ) + (`6` > 1)) >= 3)

MySQL Select problems

Table #1: qa_returns_items
Table #2: qa_returns_residues
I have a long time trying to get this Result:
item_code - item_quantity
2 - 1
3 - 2
IF qa_returns_items.item_code = qa_returns_residues.item_code AND status_code = 11 THEN
item_quantity = qa_returns_items.item_quantity -
qa_returns_residues.item_quantity
ELSEIF qa_returns_items.item_code = qa_returns_residues.item_code AND status_code = 12 THEN
item_quantity = qa_returns_items.item_quantity +
qa_returns_residues.item_quantity
ELSE
show diferendes
END IF
I tried this Query:
select SubQueryAlias.item_code,
item_quantity
from (
select
ri.item_code
, case status_code
when 11 then ri.item_quantity - rr.item_quantity
when 12 then ri.item_quantity + rr.item_quantity
end as item_quantity
from qa_returns_residues rr
left join qa_returns_items ri
on ri.item_code = rr.item_code
WHERE ri.returnlog_code = 1
) as SubQueryAlias
where item_quantity > 0 GROUP BY (item_code);
The query returns this result:
item_code - item_quantity
1 - 2
2 - 2
Try this query. I havn't tested it. It is very difficult what you require. But I have built it from table structure and given condition clause.
select qa_returns_items.item_code,
(CASE status_code
WHEN 11 THEN (qa_returns_items.item_quantity - qa_returns_residues.item_quantity)
WHEN 12 THEN (qa_returns_items.item_quantity + qa_returns_residues.item_quantity) END) as item_quantity ,
qa_returns_residues.item_unitprice,
( qa_returns_residues.item_unitprice * item_quant) as item_subtotal,
(qa_returns_residues.item_discount * item_quantity) as item_discount,
( ( qa_returns_residues.item_unitprice * item_quant) -
(qa_returns_residues.item_discount * item_quantity) ) as item_total
where
item_quantity > 0 AND qa_returns_items.item_code = qa_returns_residues.item_code
Update:
select qa_returns_items.item_code,
(CASE status_code
WHEN 11 THEN (qa_returns_items.item_quantity - qa_returns_residues.item_quantity)
WHEN 12 THEN (qa_returns_items.item_quantity + qa_returns_residues.item_quantity) END) as item_quant ,
qa_returns_residues.item_unitprice,
( qa_returns_residues.item_unitprice * item_quant) as item_subtotal,
(qa_returns_residues.item_discount * item_quantity) as item_discount,
( ( qa_returns_residues.item_unitprice * item_quant) -
(qa_returns_residues.item_discount * item_quantity) ) as item_total
where
(CASE status_code
WHEN 11 THEN (qa_returns_items.item_quantity - qa_returns_residues.item_quantity)
WHEN 12 THEN (qa_returns_items.item_quantity + qa_returns_residues.item_quantity) END) item_quant > 0 AND qa_returns_items.item_code = qa_returns_residues.item_code
In my experience I would advice you to start over with a fresh database, no records and start debugging step by step.
First create the database and the tables. After that insert only 2 records with simple data. Afterwards start debugging.
From what I was able to debug the problem is in your sub-select. In the topic you want to see item_code 2 and 3. That can't happen because:
SELECT ri.item_code,
CASE status_code
WHEN 11 then ri.item_quantity - rr.item_quantity
WHEN 12 then ri.item_quantity + rr.item_quantity
END AS item_quantity
FROM qa_returns_residues rr
LEFT JOIN qa_returns_items ri
ON ri.item_code = rr.item_code
WHERE ri.returnlog_code = 1 // Why do you need this for ?
returns
item_code item_quantity
2 2
1 0
1 0
1 0
1 2
And then the main query selects only the results which have item_quantity > 0.
Thus you get only
item_code item_quantity
1 2
2 2
as a result.
I'm not quite sure what's the purpose of this operation but have in mind that simple solutions are always best!
I solved my problem:
SELECT
item_code,
item_quantity,
item_unitprice,
item_subtotal,
item_discount,
item_total
FROM (
SELECT qa_returns_items.item_code,
qa_returns_items.item_quantity,
qa_returns_items.item_unitprice,
qa_returns_items.item_subtotal,
qa_returns_items.item_discount,
qa_returns_items.item_total
FROM qa_returns_items
WHERE returnlog_code = 1
UNION
SELECT qa_returns_residues.item_code,
qa_returns_residues.item_quantity,
qa_returns_residues.item_unitprice,
qa_returns_residues.item_subtotal,
qa_returns_residues.item_discount,
qa_returns_residues.item_total
FROM qa_returns_residues
WHERE returnlog_code = 1
ORDER BY item_code ASC
)
AS SubQueryAlias
WHERE item_code NOT IN (
SELECT a.item_code
FROM qa_returns_items a
JOIN qa_returns_residues b
ON b.item_code = a.item_code
WHERE a.returnlog_code = 1
AND b.returnlog_code = 1
);