It does not work collection queries with the condition - mysql

I need to bring to the customer a discount depending on how long it took a training course.
To find out the date of passage must first know the group ID to which the client belongs.
When I know Id of group, I can find date when started training course.
And then, determined the size of discounts by finded date
Here's a script that works great in MS SQL, but in MySql it doesn't works.
CREATE DEFINER=`root`#`localhost` PROCEDURE `GetBonus`(
idStudent CHAR(36)
)
BEGIN
IF (SELECT COUNT(*) FROM (SELECT IdGroupe FROM GroupeStudent WHERE IdStudent = idStudent) groupeCourse) = 1 THEN
BEGIN
DECLARE CourseGroupeDate datetime;
SET CourseGroupeDate = (SELECT Date FROM CourseGroupe WHERE Id = (SELECT IdGroupe FROM GroupeStudent WHERE IdStudent = idStudent));
IF (CourseGroupeDate - INTERVAL NOW() MONTH) < 3 AND
(CourseGroupeDate - INTERVAL NOW() MONTH) > 0
THEN SELECT * FROM Discounts WHERE Id = '00000000-0000-0000-0000-000000000000';
ELSEIF (CourseGroupeDate - INTERVAL NOW() MONTH) < 6 AND
(CourseGroupeDate - INTERVAL NOW() MONTH) > 3
THEN SELECT * FROM Discounts WHERE Id = '00000000-0000-0000-0000-000000000001';
ELSEIF (CourseGroupeDate - INTERVAL NOW() MONTH) < 12 AND
(CourseGroupeDate - INTERVAL NOW() MONTH) > 6
THEN SELECT * FROM Discounts WHERE Id = '00000000-0000-0000-0000-000000000002';
END IF;
END;
END IF;
END

CREATE PROCEDURE `GetBonus`(
idStudent CHAR(36)
)
BEGIN
IF (SELECT COUNT(groupeCourse.IdGroupe) FROM (SELECT IdGroupe FROM GroupeStudent WHERE GroupeStudent.IdStudent = idStudent) groupeCourse) = 1 THEN
BEGIN
SET #CourseGroupeDate := (SELECT Date FROM CourseGroupe WHERE Id = (SELECT GroupeStudent.IdGroupe FROM GroupeStudent WHERE GroupeStudent.IdStudent = idStudent));
IF (TIMESTAMPDIFF(MONTH, #CourseGroupeDate, now())) < 3 AND
(TIMESTAMPDIFF(MONTH, #CourseGroupeDate, now())) > 0
THEN SELECT * FROM Discounts WHERE Id = '00000000-0000-0000-0000-000000000000';
ELSEIF (TIMESTAMPDIFF(MONTH, #CourseGroupeDate, now())) < 6 AND
(TIMESTAMPDIFF(MONTH, #CourseGroupeDate, now())) > 3
THEN SELECT * FROM Discounts WHERE Id = '00000000-0000-0000-0000-000000000001';
ELSEIF (TIMESTAMPDIFF(MONTH, #CourseGroupeDate, now())) < 12 AND
(TIMESTAMPDIFF(MONTH, #CourseGroupeDate, now())) > 6
THEN SELECT * FROM Discounts WHERE Id = '00000000-0000-0000-0000-000000000002';
END IF;
END;
END IF;
END
All in the details , for example , it was necessary to specify the table name about the field GroupeStudent.IdStudent = idStudent

Related

QOQ growth Mysql

i have query
select a.`2021`,
b.`2022`,
a.product,
concat(ceil((b.`2022`-a.`2021`)/ a.`2021` * 100), '%') as growth
from ( SELECT SUM(total) as `2021`,
product,
sum
FROM table
WHERE YEAR(month) = 2021
AND case when day(CURRENT_DATE()) > 10
then QUARTER(month) = QUARTER(CURRENT_DATE() - INTERVAL 1 MONTH)
else QUARTER(month) = QUARTER(CURRENT_DATE() - INTERVAL 3 MONTH)
end
GROUP BY Product ,
YEAR(month) )a
JOIN ( SELECT SUM(total) as `2022`,
Product
FROM table
WHERE YEAR(month) = 2022
AND case when day(CURRENT_DATE()) > 10
then QUARTER(month) = QUARTER(CURRENT_DATE() - INTERVAL 1 MONTH)
else QUARTER(month) = QUARTER(CURRENT_DATE() - INTERVAL 3 MONTH)
end
GROUP BY Product ,
YEAR(month) ) b on a.Product=b.Product;
if the current date is not the end of the quarter then the data that appears is the data in the previous quarter period

run multiple mysql queries as 1 query

im trying to take 3 sql queries and insert them into 1 table without getting the null value's and using a group by number as to not get duplicate numbers in the same column.
I have the issue where running query 1 leaves me with a bunch of null data values
and running query 2 doesnt group the numbers resulting in thousands of rows numbers only go up to 100
QUERY 1
insert into table ( number)
select number as 1day from table where date = CURDATE() - interval 1day group by number
insert into table ( number)
select number as 2day from table where date = CURDATE() - interval 1day group by number
insert into table ( number)
select number as 7day from table where date = CURDATE() - interval 1day group by number
so i try to run
QUERY 2
insert into table (number,number,number)
select
*
from
(select number as 1day from test.test where date = curdate() - interval 1 day group by
number) as 1day,
(select number as 2day from test.test where date > curdate() - interval 2 day group by
number) as 2day,
(select number as 7day from test.test where date > curdate() - interval 7 day group
by number) as 7day;
try the below:
insert into table (number,number,number)
select
table.1day,table.2day,table.7day
from
((select number from test.test where date = curdate() - interval 1 day group by
number) as 1day,
(select numberfrom test.test where date > curdate() - interval 2 day group by
number) as 2day,
(select number from test.test where date > curdate() - interval 7 day group
by number) as 7day) as table
select (case one.number when two.number then null else one.number end) as '1day',(case two.number <= third.number when true then (case one.number = two.number when true then null else two.number end) else (case one.number = two.number when false then null else two.number end) end) as '2day',(case (third.number < one.number and third.number = two.number) when true then null else third.number end) as '7day'
from (
(select x.number
from (
(select number,'1day' as 'type' from testtable where date = curdate() - interval 1 day group by number)
union all
(select number,'2day' as 'type' from testtable where date > curdate() - interval 2 day group by number)
union all
(select number,'7day' as 'type' from testtable where date > curdate() - interval 7 day group by number)) as x
where x.type='2day' order by x.number) as two,
(select x.number
from (
(select number,'1day' as 'type' from testtable where date = curdate() - interval 1 day group by number)
union all
(select number,'2day' as 'type' from testtable where date > curdate() - interval 2 day group by number)
union all
(select number,'7day' as 'type' from testtable where date > curdate() - interval 7 day group by number)) as x
where x.type='1day' order by x.number) as one,
(select x.number
from (
(select number,'1day' as 'type' from testtable where date = curdate() - interval 1 day group by number)
union all
(select number,'2day' as 'type' from testtable where date > curdate() - interval 2 day group by number)
union all
(select number,'7day' as 'type' from testtable where date > curdate() - interval 7 day group by number)) as x
where x.type='7day' order by x.number) as third
)
where ((one.number = two.number) or (one.number is null or two.number is null)) or
((third.number = two.number) or (two.number is null or third.number is null))

Update two columns of two different table in single query with order by and limit-mysql

Query
UPDATE vcd_resorts AS resorts,
vcd_deals AS deals
SET resorts.rst_live_date = Date_add(Curdate(), INTERVAL 4 day),
deals.del_date = Date_add(Curdate(), INTERVAL 4 day)
WHERE 0 = (SELECT resort_id_count
FROM (SELECT Count(rst_id) AS resort_id_count
FROM vcd_resorts
WHERE rst_supersaver_resort = 1
AND rst_live_date BETWEEN Curdate() + 1 AND
Curdate() + 4)
temp)
AND resorts.rst_supersaver_resort = 1
AND resorts.rst_id = deals.del_resort_id
AND deals.del_supersaver_deal = 1
ORDER BY resorts.rst_live_date ASC
LIMIT 1
Error
#1221 - Incorrect usage of UPDATE and ORDER BY
what is wrong in this and any other way to do this
There is no sense of using ORDER BY in Update. Because the command updates all the matching orders no matter in what sequence.
Use Update command without ORDER BY clause as:
UPDATE vcd_resorts AS resorts,
vcd_deals AS deals
SET resorts.rst_live_date = Date_add(Curdate(), INTERVAL 4 day),
deals.del_date = Date_add(Curdate(), INTERVAL 4 day)
WHERE 0 = (SELECT resort_id_count
FROM (SELECT Count(rst_id) AS resort_id_count
FROM vcd_resorts
WHERE rst_supersaver_resort = 1
AND rst_live_date BETWEEN Curdate() + 1 AND
Curdate() + 4)
temp)
AND resorts.rst_supersaver_resort = 1
AND resorts.rst_id = deals.del_resort_id
AND deals.del_supersaver_deal = 1
LIMIT 1
i got solution of this question
UPDATE vcd_resorts AS resorts,
vcd_deals AS deals
SET resorts.rst_live_date = Date_add(Curdate(), INTERVAL 4 day),
deals.del_date = Date_add(Curdate(), INTERVAL 4 day)
WHERE 0 = (SELECT resort_id_count
FROM (SELECT Count(rst_id) AS resort_id_count
FROM vcd_resorts
WHERE rst_supersaver_resort = 1
AND rst_live_date BETWEEN Curdate() + 1 AND
Curdate() + 4)
temp)
AND resorts.rst_supersaver_resort = 1
AND resorts.rst_id = deals.del_resort_id
AND deals.del_supersaver_deal = 1
AND resorts.rst_id = (SELECT resort_id
FROM (SELECT rst_id AS resort_id
FROM vcd_resorts
WHERE rst_supersaver_resort = 1
ORDER BY rst_live_date ASC
LIMIT 1) temp1)
i have placed one more condition which replaced order by and limit

Get total hours worked between 2 days mysql

I have a MySQL table where employee login and logout timings are recorded. Here in the in-out column 1-represents login and 0-represents logout.
[id] [User_id] [Date_time] [in_out]
1 1 2011-01-20 18:01:03 1
2 1 2011-01-20 19:30:43 0
3 1 2011-01-20 20:46:23 1
4 1 2011-01-21 00:42:45 0
Is it possible to retrieve total hours worked in a day (between 2 days) by a user using single query?
The same Question it's a copy of Get total hours worked in a day mysql and solution:
SELECT `User_id`, time(sum(`Date_time`*(1-2*`in_out`)))
FROM `whatever_table` GROUP BY `User_id`;
But the solution needs to be different when the employee start working in a day and go out on the next day.
You can achieve this using given stored procedure. Consider your table name EventLog.
DELIMITER $$
CREATE PROCEDURE `GET_TOTAL_LOGIN_TIME`(
IN startDate DATETIME,
IN endDate DATETIME,
IN userId INT(11)
)
BEGIN
select
(sum(
case when(e2.Date_time <= startDate) then 0 else
case when(e1.Date_time >= endDate) then 0 else
case when(e1.Date_time >= startDate && e2.Date_time <= endDate) then
TIME_TO_SEC(TIMEDIFF(e2.Date_time, e1.Date_time))/60 else
case when(e1.Date_time <= startDate && e2.Date_time <= endDate) then
TIME_TO_SEC(TIMEDIFF(e2.Date_time, startDate))/60 else
case when(e1.Date_time >= startDate && e2.Date_time >= endDate) then
TIME_TO_SEC(TIMEDIFF(endDate,e1.Date_time))/60
end end end end end
)) as loginTimeInMin
from
((EventLog e1
left join EventLog e2 ON (((e1.User_id = e2.User_id) and (e2.in_out = 0) and (e1.Date_time < e2.Date_time))))
left join EventLog e3 ON (((e1.User_id = e3.User_id) and (e1.Date_time < e3.Date_time) and (e3.Date_time < e2.Date_time))))
where
((e1.in_out = 1) and isnull(e3.Date_time)) and e2.Date_time is not null
AND e1.User_id = userId
AND userRole.userRoleId = roleId
AND userRole.userLoginId = userId
group by e1.User_id;
END;
You can get the number of seconds worked like this:
SELECT `User_id`, sum(unix_timestamp(`Date_time`)*(1-2*`in_out`))
FROM `whatever_table`
GROUP BY `User_id`;
Then you can convert the seconds to whatever you want.

Count days between two dates, excluding weekends (MySQL only)

I need to calculate the difference (in days) between two dates in MySQL excluding weekends (Saturday and Sunday). That is, the difference in days minus the number of Saturday and Sunday in between.
At the moment, I simply count the days using:
SELECT DATEDIFF('2012-03-18', '2012-03-01')
This return 17, but I want to exclude weekends, so I want 12 (because the 3rd and 4th, 10th and 11th and 17th are weekends days).
I do not know where to start. I know about the WEEKDAY() function and all related ones, but I do not know how to use them in this context.
Simply try it using a simple function :
CREATE FUNCTION TOTAL_WEEKDAYS(date1 DATE, date2 DATE)
RETURNS INT
RETURN ABS(DATEDIFF(date2, date1)) + 1
- ABS(DATEDIFF(ADDDATE(date2, INTERVAL 1 - DAYOFWEEK(date2) DAY),
ADDDATE(date1, INTERVAL 1 - DAYOFWEEK(date1) DAY))) / 7 * 2
- (DAYOFWEEK(IF(date1 < date2, date1, date2)) = 1)
- (DAYOFWEEK(IF(date1 > date2, date1, date2)) = 7);
Test :
SELECT TOTAL_WEEKDAYS('2013-08-03', '2013-08-21') weekdays1,
TOTAL_WEEKDAYS('2013-08-21', '2013-08-03') weekdays2;
Result :
| WEEKDAYS1 | WEEKDAYS2 |
-------------------------
| 13 | 13 |
Illustration:
mtwtfSSmtwtfSS
123456712345 one week plus 5 days, you can remove whole weeks safely
12345------- you can analyze partial week's days at start date
-------12345 or at ( end date - partial days )
Pseudocode:
#S = start date
#E = end date, not inclusive
#full_weeks = floor( ( #E-#S ) / 7)
#days = (#E-#S) - #full_weeks*7 OR (#E-#S) % 7
SELECT
#full_weeks*5 -- not saturday+sunday
+IF( #days >= 1 AND weekday( S+0 )<=4, 1, 0 )
+IF( #days >= 2 AND weekday( S+1 )<=4, 1, 0 )
+IF( #days >= 3 AND weekday( S+2 )<=4, 1, 0 )
+IF( #days >= 4 AND weekday( S+3 )<=4, 1, 0 )
+IF( #days >= 5 AND weekday( S+4 )<=4, 1, 0 )
+IF( #days >= 6 AND weekday( S+5 )<=4, 1, 0 )
-- days always less than 7 days
Below function will give you the Weekdays, Weekends, Date difference with proper results:
You can call the below function like,
select getWorkingday('2014-04-01','2014-05-05','day_diffs');
select getWorkingday('2014-04-01','2014-05-05','work_days');
select getWorkingday('2014-04-01','2014-05-05','weekend_days');
DROP FUNCTION IF EXISTS PREPROCESSOR.getWorkingday;
CREATE FUNCTION PREPROCESSOR.`getWorkingday`(d1 datetime,d2 datetime, retType varchar(20)) RETURNS varchar(255) CHARSET utf8
BEGIN
DECLARE dow1, dow2,daydiff,workdays, weekenddays, retdays,hourdiff INT;
declare newstrt_dt datetime;
SELECT dd.iDiff, dd.iDiff - dd.iWeekEndDays AS iWorkDays, dd.iWeekEndDays into daydiff, workdays, weekenddays
FROM (
SELECT
dd.iDiff,
((dd.iWeeks * 2) +
IF(dd.iSatDiff >= 0 AND dd.iSatDiff < dd.iDays, 1, 0) +
IF (dd.iSunDiff >= 0 AND dd.iSunDiff < dd.iDays, 1, 0)) AS iWeekEndDays
FROM (
SELECT dd.iDiff, FLOOR(dd.iDiff / 7) AS iWeeks, dd.iDiff % 7 iDays, 5 - dd.iStartDay AS iSatDiff, 6 - dd.iStartDay AS iSunDiff
FROM (
SELECT
1 + DATEDIFF(d2, d1) AS iDiff,
WEEKDAY(d1) AS iStartDay
) AS dd
) AS dd
) AS dd ;
if(retType = 'day_diffs') then
set retdays = daydiff;
elseif(retType = 'work_days') then
set retdays = workdays;
elseif(retType = 'weekend_days') then
set retdays = weekenddays;
end if;
RETURN retdays;
END;
Thank You.
Vinod Cyriac.
Bangalore
IT my helpful to you
The bellow logic only show the how many days
like
sun mon
1 2 .....................
DELIMITER $$
DROP FUNCTION IF EXISTS `xx`.`get_weekday` $$
CREATE FUNCTION `xx`.`get_weekday` (first_date date, last_date date, curr_week_day int) RETURNS INT
BEGIN
DECLARE days_tot int;
DECLARE whole_weeks int;
DECLARE first_day int;
DECLARE last_day int;
SET whole_weeks = FLOOR(DATEDIFF(last_date,first_date)/7) ;
SET first_day = WEEKDAY(first_date) ;
SET last_day = WEEKDAY(last_date) ;
IF curr_week_day BETWEEN first_day AND last_day
AND last_day > first_day
OR ( curr_week_day BETWEEN last_day AND first_day
AND last_day < first_day )
THEN SET days_tot = whole_weeks + 1;
ELSE SET days_tot = whole_weeks ;
END IF;
RETURN days_tot;
END $$
DELIMITER ;
SELECT
`xx`.`get_weekday` ('2009-01-01', '2009-07-20', 0) as mo,
`xx`.`get_weekday` ('2009-01-01', '2009-07-20', 1) as tu,
`xx`.`get_weekday` ('2009-01-01', '2009-07-20', 2) as we,
`xx`.`get_weekday` ('2009-01-01', '2009-07-20', 3) as th,
`xx`.`get_weekday` ('2009-01-01', '2009-07-20', 4) as fr,
`xx`.`get_weekday` ('2009-01-01', '2009-07-20', 5) as sa,
`xx`.`get_weekday` ('2009-01-01', '2009-07-20', 6) as su;
Table based query
ip:
Weekday count
2 10
3 5
SELECT WEEKDAY( `req_date_time` ) AS weekday, COUNT( id ) AS id
FROM `ddd`
WHERE (
`req_date_time` >= '2014-12-01'
AND `req_date_time` <= '2014-12-31'
)
AND WEEKDAY( `req_date_time` ) != '1'
GROUP BY WEEKDAY( `req_date_time` )
You can use a dates table:
tbl_dates
dow is 'day of week' in my table. Then your query looks like this:
SELECT Count(theDate) AS numWeekDays
FROM tbl_dates
WHERE theDate >[startDate] And theDate <=[endDate] AND dow <> 1 AND dow <> 7;
In this case, 1 and 7 are Sunday, Saturday, respectively (which is the default) and, of course, you can nest that into another query if you need to calculate this for many startDate(s) and endDate(s).