subtracting days from a given day in mysql - mysql

Personal leave is 10 days. I need the remaining leave to be subtracted from the total personal leave i.e 10 days
result i have
SELECT id, firstname,lastname,join_date, completion_date,title, leave_from,leave_to, Given_leave_Days,Taken_Leave_Days,Remaining_Leave_Days FROM (SELECT T1.id,T1.firstname,T1.lastname,T1.join_date,T1.completion_date,T0.title,T2.leave_from,T2.leave_to,T2.user_id,T0.Leave_Days as Given_leave_Days,SUM(DATEDIFF(T2.leave_to,T2.leave_from)+1) AS Taken_Leave_Days ,T0.Leave_Days - SUM(DATEDIFF(T2.leave_to,T2.leave_from)+1) as 'Remaining_Leave_Days' FROM users_leave_request T2 INNER JOIN users T1 ON T2.user_id = T1.id INNER JOIN leave_type T0 ON T2.leave_type_id = T0.id GROUP BY T1.id, T1.firstname, T1.lastname, T1.join_date,T1.completion_date,T0.title,T2.leave_from,T2.leave_to,Given_leave_Days order by firstname) A
i have to display the result in frontend.
result in frontend

The general answer is
select date_sub(now(), interval 10 day)
You can replace now() for any date from a table, you can change day for month, year, etc.
The result from my example is a date 10 days before today. For example, if you want to filter only the dates older than 10 days you would do like this:
select * from mytable t where t.mydate < date_sub(now(), interval 10 day)

Related

Mysql query record customer and last activity older than 30 days

this is my table
I wish to query the customer that didn't have any record within 30days
I try this query
SELECT *,DATE_FORMAT(date, '%m/%d/%Y')
FROM transaction
WHERE date <= DATE_SUB(SYSDATE(), INTERVAL 30 DAY)
AND type = 'deposit'
ORDER BY trans_id DESC
but it will return all the data older than 30 days,
my aim is to get the user who have no new record within 30 days, so it should only show testuser2
how can I make it?
You could try using a left join on the customer with transcation <= 30 anche check for not matching values
SELECT t1.*,DATE_FORMAT(t1.date, '%m/%d/%Y')
FROM transaction t1
LEFT JOIN (
SELECT customer FROM transaction
WHERE date <= DATE_SUB(SYSDATE(), INTERVAL 30 DAY)
) t2 ON t2customer = t1.customer
WHERE t1.date <= DATE_SUB(SYSDATE(), INTERVAL 30 DAY)
AND t1.type = 'deposit'
AND t2.customer IS NULL
ORDER BY trans_id DESC

MySQL Select Query for taking data within specific time in two tables

I have below two tables in pasted scree shot,
Query with these table is fine for me to take data for last 24 hrs as this will give me 1st device in the table.
now I need new query that 2nd device in T1 also should come because this device create time in T1 is within 24 hrs of T2 insert time.
3rd device in T1 should not come in my query result because its create time in T1 is greater than 24 hrs than insert time in T2.
I am looking query for the last two points.
Select a.device,[a.create time], b.device, [b.insert time]
from T1 a, T2 b
where a.device = b.device and a.time >= DATE_SUB(NOW(), INTERVAL 24 HOUR)
The a.device = b.device should be your join condition.
Select a.device,[a.create time], b.device, [b.insert time]
from T1 a inner join T2 b on a.device = b.device
where
a.time >= DATE_SUB(NOW(), INTERVAL 24 HOUR) --first condtion
or a.time <= DATE_SUB(b.time, INTERVAL 24 HOUR) --second condition

Difficult query for calculating user appeared certain days before

I have a table
id, date
a , 2017-01-01
a , 2017-01-02
b , 2017-02-03
...
and I'd like to compute for each day D, how many distinct user appeared exactly 7 days ago (on that day), but not in-between D-7 and D. Don't care about if they appear before day D
And the output shall be
date, count
2017-01-01, 23
2017-01-02, 33
etc
I've been thinking about this for quite a while, but can't figure out the D to D+7 part out. Easily converted into python, but I'd like to sharpen my SQL skills :)
I know basic select, group by clauses, but I'm just wondering if there're any advanced techniques I should know about.
Any help would be appreciated
You can check if the user appeared on that day and 7 days ago
SELECT DDate,
COUNT(*) cnt
FROM tablename a
WHERE id IN (SELECT id
FROM tablename
WHERE DDate = DATE_SUB(a.DDate, INTERVAL 7 DAY)
)
GROUP BY DDate
I'm just trying to help you with the assumption of what I understand about your question
just from the documentation
select count(date), date from tablename where date<=CURDATE() + interval 7 day group by date
You can use a left join on the same table for the 7 days in the future to see if the ID shows up. If it doesn't show up, the left joined table's id will be null.
select count(distinct t1.id), t1.date + interval 7 day
from table t1
left join table t2 on t2.id = t1.id and t2.date < t1.date + interval 7 day and t2.date >= t1.date
where t2.id is null;
Similar to Ferdinand Gasper's answer, but this excludes the users who appeared less than 7 days before:
SELECT date, COUNT(DISTINCT id)
FROM yourTable AS t1
WHERE id IN (SELECT id
FROM yourTable AS t2
WHERE t2.date = DATE_SUB(t1.date, INTERVAL 7 DAY))
AND id NOT IN (SELECT id
FROM yourTable AS t2
WHERE t2.date BETWEEN DATE_SUB(t1.date, INTERVAL 6 DAY) AND DATE_SUB(t1.date, INTERVAL 1 DAY))
GROUP BY date

mysql multiple tables select last 7 days

I am having 3 tables, containing some records which have a date and a numeric value (the tables can't be merged). I want to make up a bar chart using the information from the tables. The bar chart is grouped by days and should display the last seven days.
Earlier i had two tables and used the following query-scheme:
SELECT
t.credits1,
t.credits2,
t.date
FROM
(
(
SELECT
t1.credits1,
t2.credits2,
t1.date
FROM
(
SELECT
SUM(credits) AS credits1,
date
FROM
table1
WHERE
table1.date >= DATE_SUB(CURDATE(), INTERVAL 7 DAY)
GROUP BY
DATE(table1.date)
) t1
LEFT JOIN
(
SELECT
SUM(credits) AS credits2,
date
FROM
table2
WHERE
table2.date >= DATE_SUB(CURDATE(), INTERVAL 7 DAY)
GROUP BY
DATE(table2.date)
) t2
ON t1.date = t2.date
)
UNION
(
SELECT
t1.credits1,
t2.credits2,
t1.date
FROM
(
SELECT
SUM(credits) AS credits1,
date
FROM
table1
WHERE
table1.date >= DATE_SUB(CURDATE(), INTERVAL 7 DAY)
GROUP BY
DATE(table1.date)
) t1
RIGHT JOIN
(
SELECT
SUM(credits) AS credits2,
date
FROM
table2
WHERE
table2.date >= DATE_SUB(CURDATE(), INTERVAL 7 DAY)
GROUP BY
DATE(table2.date)
) t2
ON t1.date = t2.date
)
) t GROUP BY
DATE(date)
(pseudo code)
But how can i do this with more than 2 tables?
Is there any chance to set the dates of the past 7 days as a base, so that i get 7 records everytime?
To point out the problem: If I dont have records in the first table for a day, i won't get the records from the other tables for that day.
I assume the 3 tables have similar schemas? Try using UNION ALL to join the tables together.
SELECT ABB1.date, SUM(ABB1.credit) AS daily_total
FROM
(SELECT date, credits
FROM table1
UNION ALL
SELECT date, credits
FROM table1
UNION ALL
SELECT date, credits
FROM table2) AS ABB1
WHERE DATE >= DATE_SUB(CURDATE(), INTERVAL 7 DAY)

Return a zero for a day with no results

I have a query which returns the total of users who registered for each day. Problem is if a day had no one register it doesn't return any value, it just skips it. I would rather it returned zero
this is my query so far
SELECT count(*) total FROM users WHERE created_at < NOW() AND created_at >
DATE_SUB(NOW(), INTERVAL 7 DAY) AND owner_id = ? GROUP BY DAY(created_at)
ORDER BY created_at DESC
Edit
i grouped the data so i would get a count for each day- As for the date range, i wanted the total users registered for the previous seven days
A variation on the theme "build your on 7 day calendar inline":
SELECT D, count(created_at) AS total FROM
(SELECT DATE_SUB(NOW(), INTERVAL D DAY) AS D
FROM
(SELECT 0 as D
UNION SELECT 1
UNION SELECT 2
UNION SELECT 3
UNION SELECT 4
UNION SELECT 5
UNION SELECT 6
) AS D
) AS D
LEFT JOIN users ON date(created_at) = date(D)
WHERE owner_id = ? or owner_id is null
GROUP BY D
ORDER BY D DESC
I don't have your table structure at hand, so that would need adjustment probably. In the same order of idea, you will see I use NOW() as a reference date. But that's easily adjustable. Anyway that's the spirit...
See for a live demo http://sqlfiddle.com/#!2/ab5cf/11
If you had a table that held all of your days you could do a left join from there to your users table.
SELECT SUM(CASE WHEN U.Id IS NOT NULL THEN 1 ELSE 0 END)
FROM DimDate D
LEFT JOIN Users U ON CONVERT(DATE,U.Created_at) = D.DateValue
WHERE YourCriteria
GROUP BY YourGroupBy
The tricky bit is that you group by the date field in your data, which might have 'holes' in it, and thus miss records for that date.
A way to solve it is by filling a table with all dates for the past 10 and next 100 years or so, and to (outer)join that to your data. Then you will have one record for each day (or week or whatever) for sure.
I had to do this only for MS SqlServer, so how to fill a date table (or perhaps you can do it dynamically) is for someone else to answer.
A bit long winded, but I think this will work...
SELECT count(users.created_at) total FROM
(SELECT DATE_SUB(CURDATE(),INTERVAL 6 DAY) as cdate UNION ALL
SELECT DATE_SUB(CURDATE(),INTERVAL 5 DAY) UNION ALL
SELECT DATE_SUB(CURDATE(),INTERVAL 4 DAY) UNION ALL
SELECT DATE_SUB(CURDATE(),INTERVAL 3 DAY) UNION ALL
SELECT DATE_SUB(CURDATE(),INTERVAL 2 DAY) UNION ALL
SELECT DATE_SUB(CURDATE(),INTERVAL 1 DAY) UNION ALL
SELECT CURDATE()) t1 left join users
ON date(created_at)=t1.cdate
WHERE owner_id = ? or owner_id is null
GROUP BY t1.cdate
ORDER BY t1.cdate DESC
It differs from your query slightly in that it works on dates rather than date times which your query is doing. From your description I have assumed you mean to use whole days and therefore have used dates.