Cannot get 180 day sql date to work - mysql

SELECT CTT.BAN, `Company`, `CID`, `FName`, `MInit`,
`LName`, `OName`, `Address`, `City`, `State`,
`PostalCode`, `ActiveDate`, `ClosedDate`, `Draft`,
`Credit`, `BillingCycle`, `BillingFreq`, `Suspended`,
`Paperless` , BTT.Bal
FROM CustomerT CTT
JOIN BalanceT BTT
ON (CTT.BAN = BTT.BAN)
WHERE `Paperless` != '1'
AND `BankDraft` != -1
AND `CreditCard` != -1
AND (`BillingCycle` = '1' OR `BillingCycle` = '0')
AND `Bal` > 2
AND (`AccountClosedDate` IS NULL OR
DATE(`AccountClosedDate`) >= (NOW() - INTERVAL 180 DAY) )
Everything works with this query but the 180 date peice i have tried several things from this site, with no luck. I need to include into the table only the last 6 months closed acount.

try this with DATE_ADD
SELECT CTT.BAN, `Company`, `CID`, `FName`, `MInit`, `LName`, `OName`, `Address`, `City`, `State`, `PostalCode`, `ActiveDate`, `ClosedDate`, `Draft`, `Credit`, `BillingCycle`, `BillingFreq`, `Suspended`, `Paperless` , BTT.Bal
FROM CustomerT CTT
JOIN BalanceT BTT ON
(CTT.BAN = BTT.BAN)
WHERE `Paperless` != '1'
AND `BankDraft` != -1
AND `CreditCard` != -1
AND (`BillingCycle` = '1' OR `BillingCycle` = '0')
AND `Bal` > 2
AND (`AccountClosedDate` IS NULL OR DATE(`AccountClosedDate`) >=DATE_ADD(CURDATE(), INTERVAL -180 DAY))
or use ( CURDATE() - INTERVAL 180 DAY )
SELECT CTT.BAN, `Company`, `CID`, `FName`, `MInit`, `LName`, `OName`, `Address`, `City`, `State`, `PostalCode`, `ActiveDate`, `ClosedDate`, `Draft`, `Credit`, `BillingCycle`, `BillingFreq`, `Suspended`, `Paperless` , BTT.Bal
FROM CustomerT CTT
JOIN BalanceT BTT ON
(CTT.BAN = BTT.BAN)
WHERE `Paperless` != '1'
AND `BankDraft` != -1
AND `CreditCard` != -1
AND (`BillingCycle` = '1' OR `BillingCycle` = '0')
AND `Bal` > 2
AND (`AccountClosedDate` IS NULL OR DATE(`AccountClosedDate`) >=( CURDATE() - INTERVAL 180 DAY ))

Related

How to get difference or delta of counts entries of each days with window functions?

I have a table with few fields like id, country, ip, created_at. Then I am trying to get the deltas between total entry of one day and total entry of the next day.
CREATE TABLE session (
id int NOT NULL AUTO_INCREMENT,
country varchar(50) NOT NULL,
ip varchar(255),
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id)
);
INSERT INTO `session` (`id`, `country`, `ip`, `created_at`) VALUES
('1', 'IN', '10.100.102.11', '2021-04-05 20:26:02'),
('2', 'IN', '10.100.102.11', '2021-04-05 19:26:02'),
('3', 'US', '10.120.102.11', '2021-04-17 10:26:02'),
('4', 'US', '10.100.112.11', '2021-04-16 12:26:02'),
('5', 'AU', '10.100.102.122', '2021-04-12 19:36:02'),
('6', 'AU', '10.100.102.122', '2021-04-12 18:20:02'),
('7', 'AU', '10.100.102.122', '2021-04-12 23:26:02'),
('8', 'US', '10.100.102.2', '2021-04-16 21:33:01'),
('9', 'AU', '10.100.102.122', '2021-04-18 20:46:02'),
('10', 'AU', '10.100.102.111', '2021-04-04 13:19:12'),
('11', 'US', '10.100.112.11', '2021-04-16 12:26:02'),
('12', 'IN', '10.100.102.11', '2021-04-05 15:26:02'),
('13', 'IN', '10.100.102.11', '2021-04-05 19:26:02');
Now I have written this query to get the delta
SELECT T1.date1 as date, IFNULL(T1.cnt1-T2.cnt2, T1.cnt1) as delta from (
select TA.dateA as date1, MAX(TA.countA) as cnt1 from (
select DATE(created_at) AS dateA, COUNT(*) AS countA
FROM session
GROUP BY DATE(created_at)
UNION
select DISTINCT DATE(DATE(created_at)+1) AS dateA, 0 AS countA
FROM session
) as TA
group by TA.dateA
) as T1
LEFT OUTER JOIN (
select DATE(DATE(created_at)+1) AS date2,
COUNT(*) AS cnt2
FROM session
GROUP BY DATE(created_at)
) as T2
ON T1.date1=T2.date2
ORDER BY date;
http://sqlfiddle.com/#!9/4f5fd26/60
Then I am getting the results as
date delta
2021-04-04 1
2021-04-05 3
2021-04-06 -4
2021-04-12 3
2021-04-13 -3
2021-04-16 3
2021-04-17 -2
2021-04-18 0
2021-04-19 -1
Now, is there any place of improvements/optimizes on it with/or window functions? (I am zero with SQL, still playing around).
Try a shorter version
with grp as (
SELECT t.dateA, SUM(t.cnt) AS countA
FROM session,
LATERAL (
select DATE(created_at) AS dateA, 1 as cnt
union all
select DATE(DATE(created_at)+1), 0 as cnt
) t
GROUP BY dateA
)
select t1.dateA as date, IFNULL(t1.countA-t2.countA, t1.countA) as delta
from grp t1
left join grp t2 on DATE(t2.dateA + 1) = t1.dateA
order by t1.dateA
db<>fiddle

Maria DB - update row with value of previous row + constant

I have table called dobridol with several column.
CREATE TABLE IF NOT EXISTS `dobridol` (
`id` int(6) unsigned NOT NULL,
`dt` varchar(200) NOT NULL,
`p2` int(6) NOT NULL,
`p6` int(6) NOT NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;
INSERT INTO `dobridol` (`id`, `dt`, `p2`,`p6`) VALUES
('1', '2021-02-28 23:50:00', '100', '600'),
('2', '2021-02-28 23:55:00', '200', '700'),
('3', '2021-03-01 00:00:00', '300', '800'),
('4', '2021-03-01 00:05:00', '400', '900'),
('5', '2021-03-01 00:10:00', '400', '900'),
('6', '2021-03-01 00:15:00', '400', '900'),
('7', '2021-03-01 00:20:00', '500', '1000'),
('8', '2021-03-01 00:25:00', '600', '1100');
The table has values for January and March also.
I want to be able to UPDATE table like that:
I select period as month, then I add constant value (in this case I added 39) to p6 ONLY WHEN p2 value is different than previous row p2.
If this is the case I have to add 39 to PREVIOUS row p6 value.
update dobridol join
(select tt.*,
sum(case when p2 <> prev_p2 then 1 else 0 end) over (order by dt) as cnt
from (select tt.*,
lag(p2) over (order by dt) as prev_p2
from dobridol tt
) tt
) tt
on tt.id = dobridol.id
set dobridol.p6 = cnt * 39 + <PREVIOUS_ROW_p6_VALUE_HAS_TO_BE_HERE>
where cnt > 0
The query should look-like this but I have to replace this <PREVIOUS_ROW_VALUE_HAS_TO_BE_HERE> with the right syntax of picking last row p6. How can I pick it?
Also where to add clause
dobridol.dt BETWEEN '2021-03-01' AND '2021-03-30'
in the SQL query?
If I understand correctly, you can use lag():
update dobridol join
(select tt.*,
lag(p6) over (order by dt) as prev_p6,
sum(case when p2 <> prev_p2 then 1 else 0 end) over (order by dt) as cnt
from (select tt.*,
lag(p2) over (order by dt) as prev_p2
from dobridol tt
) tt
) tt
on tt.id = dobridol.id
set dobridol.p6 = tt.cnt * 39 + tt.prev_p6
where cnt > 0 ;
Here is a db<>fiddle.

MySQL query help require

I am using MySQL database. I have employee leave table which having information about employee leave.
Please find table details:
CREATE TABLE IF NOT EXISTS `APPLY_LEAVE` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`EMP_ID` varchar(100) NOT NULL,
`TYPE_OF_LEAVE` varchar(100) NOT NULL,
`DAYS` varchar(100) NOT NULL,
`REASON` varchar(200) NOT NULL,
`START_DATE` date NOT NULL,
`END_DATE` date NOT NULL,
`STATUS` tinyint(2) NOT NULL,
`CREATED_ON` date NOT NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1;
--
-- Dumping data for table `APPLY_LEAVE`
--
INSERT INTO `APPLY_LEAVE` (`ID`, `EMP_ID`, `TYPE_OF_LEAVE`, `DAYS`, `REASON`, `START_DATE`, `END_DATE`, `STATUS`, `CREATED_ON`) VALUES
(1, 'EMP001', 'SL', '2', 'Sick Leave', '2018-11-30', '2018-12-01', 1,'2018-11-06'),
(2, 'EMP002', 'EL', '1', 'Personal', '2018-12-13', '2018-12-13', 1,'2018-11-09'),
(3, 'EMP003', 'CL', '2', 'Casual Leave due to Birthday', '2018-08-31', '2018-09-01', 1,'2018-08-20'),
(4, 'EMP001', 'CL', '3', 'Casual Leave', '2018-12-04', '2018-12-06', 1,'2018-11-27'),
(5, 'EMP002', 'SL', '4', 'Sick Leave', '2018-09-10', '2018-09-13', 1,'2018-10-04'),
(6, 'EMP003', 'SL', '3', 'Sick Leave', '2018-10-30', '2018-11-01', 1,'2018-11-25');
Require Output:
I want to generate Report/excel to receive information as month wise employee leave data based on leave type i.e (Month wise, Leave type data)
Format should be below:
Requirement: I want MySQL query to fetch attached result month wise, Leave type data(SL/CL/EL) which took by Employee.
Query tries:
SELECT EMP_ID,
SUM(CASE WHEN TYPE_OF_LEAVE = 'EL' AND MONTH( START_DATE ) =11 THEN DAYS ELSE 0 END ) AS EL_NOV,
SUM(CASE WHEN TYPE_OF_LEAVE = 'CL' AND MONTH( START_DATE ) =11 THEN DAYS ELSE 0 END ) AS CL_NOV,
SUM(CASE WHEN TYPE_OF_LEAVE = 'SL' AND MONTH( START_DATE ) =11 THEN DAYS ELSE 0 END ) AS SL_NOV,
SUM(CASE WHEN TYPE_OF_LEAVE = 'LOP' AND MONTH( START_DATE ) =11 THEN DAYS ELSE 0 END ) AS LOP_NOV,
SUM(CASE WHEN TYPE_OF_LEAVE = 'EL' AND MONTH( START_DATE ) =12 THEN DAYS ELSE 0 END ) AS EL_DEC,
SUM(CASE WHEN TYPE_OF_LEAVE = 'CL' AND MONTH( START_DATE ) =12 THEN DAYS ELSE 0 END ) AS CL_DEC,
SUM(CASE WHEN TYPE_OF_LEAVE = 'SL' AND MONTH( START_DATE ) =12 THEN DAYS ELSE 0 END ) AS SL_DEC,
SUM(CASE WHEN TYPE_OF_LEAVE = 'LOP' AND MONTH( START_DATE ) =12 THEN DAYS ELSE 0 END ) AS LOP_DEC
FROM APPLY_LEAVE
GROUP BY EMP_ID
Facing Issue:
I.e One employee look leave on Friday and Saturday (i.e EMP001 took SL on 2018-11-30 to 2018-12-01) (Friday is month of last date and Saturday is first date of month and I am inserting single record into table. When employee applied leave from application. Here result should be
EMP001 - SL
November - 1 leave
December - 1 leave
How can I write this MySQL query?
Dear Dipti Kindly find below query for required result.
SELECT
*
FROM
(
SELECT
EMP_ID,
START_DATE as date_day,
TYPE_OF_LEAVE,
SUM(
if(
MONTH(START_DATE) <> MONTH(END_DATE),
(
day(
last_day(START_DATE)
)+ 1 - day(START_DATE)
),
days
)
) as DAYS
FROM
APPLY_LEAVE
GROUP BY
MONTH(START_DATE),
MONTH(END_DATE),
EMP_ID
UNION ALL
SELECT
EMP_ID,
END_DATE as date_day,
TYPE_OF_LEAVE,
SUM(
if(
MONTH(START_DATE) <> MONTH(END_DATE),
DAY(END_DATE),
0
)
) as DAYS
FROM
APPLY_LEAVE
GROUP BY
MONTH(START_DATE),
MONTH(END_DATE),
EMP_ID
) as a
WHERE
a.DAYS > 0;

Complex insert query with insert into and where subquery in Laravel

I am trying to figure out the best way to code this using Query Builder or Eloquent.
In it's simplest form it should prevent insert of a new buy request if an item already in transactions table. I haven't found any useful reference other than running a complete raw query.
INSERT INTO `transactions`
(`user_id`, `item_id`, `type`, `created_at`, `updated_at`)
SELECT
1, 186808, 'bought', NOW(), NOW()
WHERE
(
SELECT
SUM(
CASE
WHEN `type` = 'bought' THEN 1
WHEN `type` = 'sold' THEN -1
END
)
FROM `transactions`
WHERE
(`item_id`, `user_id`) = (186808, 1)
GROUP BY `item_id`
) = 0
In Laravel, you can use DB::raw(<your_complex_query_here>) to achieve this.
DB::raw("INSERT INTO `transactions`
(`user_id`, `item_id`, `type`, `created_at`, `updated_at`)
SELECT
1, 186808, 'bought', NOW(), NOW()
WHERE
(
SELECT
SUM(
CASE
WHEN `type` = 'bought' THEN 1
WHEN `type` = 'sold' THEN -1
END
)
FROM `transactions`
WHERE
(`item_id`, `user_id`) = (186808, 1)
GROUP BY `item_id`
) = 0");
For more, refer to Laravel docs here https://laravel.com/docs/5.7/queries#raw-expressions

Using IF in MySQL's SELECT subquery

I have the following query:
SELECT `users`.`id`, `login`, `fullname`, `active`, `sex`, `height`,
`special-title`, `language`, `body-fat`,
`main-photo-id`, `main-photo-offset`, `weight`,
`objective`, `level`, `config-comments-type`,
(
SELECT `type`
FROM `users-pro`
WHERE
(`user` = `users`.`id`)
AND
(`starts` <= $time)
AND(
(`ends` > $time)
OR
(`ends` IS NULL)
)
LIMIT 1
) as `account_type`
FROM `users`
I'm wondering how/where do I add an IF statement, so that if the inner SELECT returns NULL (no entries for the user in users-pro, a value 1 would be returned.
This is what I usually do if there is no subquery:
SELECT IF(`rank` = 1, `rank`, 0) as `rank`
However, I don't know how to do this with a subquery.
You can use the ANSI standard coalesce() function for this, by wrapping the subquery in it:
SELECT `users`.`id`, `login`, `fullname`, `active`, `sex`, `height`,
`special-title`, `language`, `body-fat`,
`main-photo-id`, `main-photo-offset`, `weight`,
`objective`, `level`, `config-comments-type`,
coalesce((
SELECT `type`
FROM `users-pro`
WHERE
(`user` = `users`.`id`)
AND
(`starts` <= $time)
AND(
(`ends` > $time)
OR
(`ends` IS NULL)
)
LIMIT 1
), 1) as `account_type`
FROM `users`