Confuse query add date not in table for mysql - mysql

excuse me,
i will add date if that date not in table on mysql
example i have table
ID | name | date | clock in | clock out
---------------------------------------------------------------
1001 | A | 2013-09-18 | 09:40 | 17:15
1001 | A | 2013-09-20 | 08:20 | 17:35
1001 | A | 2013-09-21 | 08:40 | 17:40
1001 | A | 2013-09-23 | 08:10 | 17:50
so, how to add date in to no table and set clock in and clock out set null
example
ID | name | date | clock in | clock out
---------------------------------------------------------------
1001 | A | 2013-09-18 | 09:40 | 17:15
1001 | A | 2013-09-19 | null | null
1001 | A | 2013-09-20 | 08:40 | 17:40
1001 | A | 2013-09-21 | 08:10 | 17:50
1001 | A | 2013-09-22 | null | null
1001 | A | 2013-09-23 | 08:10 | 17:50
thanks

This is what you need if you're still interested:
SELECT
COALESCE(id,1001) id,
COALESCE(name,'A') name,
fixed_days.fixed_date,
clockin,clockout
FROM t
RIGHT JOIN
(SELECT CURDATE() as fixed_date
UNION ALL SELECT CURDATE() - INTERVAL 1 day
UNION ALL SELECT CURDATE() - INTERVAL 2 day
UNION ALL SELECT CURDATE() - INTERVAL 3 day
UNION ALL SELECT CURDATE() - INTERVAL 4 day
UNION ALL SELECT CURDATE() - INTERVAL 5 day
UNION ALL SELECT CURDATE() - INTERVAL 6 day) AS fixed_days
ON t.record_date = fixed_days.fixed_date
WHERE fixed_days.fixed_date <= (select max(record_date) from t);
SQL Fiddle..

Related

How to query records where one field greater than another by x days?

I have a table like:
+----+------------+------------+
| id | expiry | timestamp |
+----+------------+------------+
| 1 | 2018-11-29 | 2018-11-01 |
| 2 | 2018-12-27 | 2018-11-01 |
| 3 | 2019-01-31 | 2018-11-01 |
| 4 | 2018-11-29 | 2018-11-01 |
| 5 | 2018-12-27 | 2018-11-01 |
+----+------------+------------+
How can I query all records for which expiry is less than 30 days from timestamp? i.e.
timestamp + 30 days > expiry
I would recommend:
where expiry < timestamp + interval 30 day
you can try this
SELECT * FROM table_name WHERE DATE_ADD(TIMESTAMP , INTERVAL 30 DAY) > expiry;

get all dates in the current month

i have table
userID | date | time
===================
1 | 2015-02-08 | 06:32
1 | 2015-02-08 | 05:36
1 | 2015-02-08 | 17:43
1 | 2015-02-08 | 18:00
1 | 2015-02-09 | 06:36
1 | 2015-02-09 | 15:43
1 | 2015-02-09 | 19:00
1 | 2015-02-10 | 05:36
1 | 2015-02-10 | 17:43
1 | 2015-02-10 | 18:00
2 | 2015-02-08 | 06:32
2 | 2015-02-08 | 05:36
2 | 2015-02-08 | 17:43
2 | 2015-02-08 | 18:00
2 | 2015-02-09 | 06:36
2 | 2015-02-09 | 15:43
2 | 2015-02-09 | 19:00
2 | 2015-02-10 | 05:36
2 | 2015-02-10 | 17:43
2 | 2015-02-10 | 18:00
But i want the number of records returned to be exactly the same as the number of days of the current month and get min time for in and max time for the out. if the current month has 28 days and only had two records it should bring:
userID | date | in | out
========================
1 | 2015-02-01 | |
1 | 2015-02-02 | |
1 | 2015-02-03 | |
1 | 2015-02-04 | |
1 | 2015-02-05 | |
1 | 2015-02-06 | |
1 | 2015-02-07 | |
1 | 2015-02-08 | 06:32 | 18:00
1 | 2015-02-09 | 06:36 | 19:00
1 | 2015-02-10 | 05:36 | 18:00
1 | 2015-02-11 | |
1 | 2015-02-12 | |
1 | 2015-02-13 | |
1 | 2015-02-14 | |
1 | 2015-02-15 | |
1 | 2015-02-16 | |
1 | 2015-02-17 | |
1 | 2015-02-18 | |
1 | 2015-02-19 | |
1 | 2015-02-20 | |
1 | 2015-02-21 | |
1 | 2015-02-22 | |
1 | 2015-02-23 | |
1 | 2015-02-24 | |
1 | 2015-02-25 | |
1 | 2015-02-26 | |
1 | 2015-02-27 | |
1 | 2015-02-28 | |
How can i modify my query to achieve the above result?
this is my query:
$sql = "SELECT
colUserID,
colDate,
if(min(colJam) < '12:00:00',min(colJam), '') as in,
if(max(colJam) > '12:00:00',max(colJam), '') as out
FROM tb_kehadiran
WHERE colDate > DATE_ADD(MAKEDATE($tahun, 31),
INTERVAL($bulan-2) MONTH)
AND
colDate < DATE_ADD(MAKEDATE($tahun, 1),
INTERVAL($bulan) MONTH)
AND
colUserID = $user_id
GROUP BY colUserID,colDate";
I had to think about this one. But probably the simpliest answer so far:
WITH AllMonthDays as (
SELECT n = 1
UNION ALL
SELECT n + 1 FROM AllMonthDays WHERE n + 1 <= DAY(EOMONTH(GETDATE()))
)
SELECT
DISTINCT datefromparts(YEAR(GETDATE()), MONTH(GETDATE()), n) As dates
, MIN(d.time) as 'In'
, MAX(d.time) as 'Out'
FROM AllMonthDays as A
LEFT OUTER JOIN
table as d on
DAY(d.date) = A.n
GROUP BY n,(d.date);
--- Test and tried in this environment: ---
use Example;
CREATE TABLE demo (
ID int identity(1,1)
,date date
,time time
);
INSERT INTO demo (date, time) VALUES
('2015-12-08', '06:32'),
('2015-12-08', '05:36'),
('2015-12-08', '17:43'),
('2015-12-08', '18:00'),
('2015-12-09', '06:36'),
('2015-12-09', '15:43'),
('2015-12-09', '19:00'),
('2015-12-10', '05:36'),
('2015-12-10', '17:43'),
('2015-12-10', '18:00')
;
WITH AllMonthDays as (
SELECT n = 1
UNION ALL
SELECT n + 1 FROM AllMonthDays WHERE n + 1 <= DAY(EOMONTH(GETDATE()))
)
SELECT
DISTINCT datefromparts(YEAR(GETDATE()), MONTH(GETDATE()), n) As dates
, MIN(d.time) as 'In'
, MAX(d.time) as 'Out'
FROM AllMonthDays as A
LEFT OUTER JOIN
demo as d on
DAY(d.date) = A.n
GROUP BY n,(d.date);
DROP table demo;
The way I've approached this problem in the past is to have a date table that is pre-populated for some years in the future.
You could create such a table, possibly defining columns for year, month and date, with indexes on year and month.
You can then use this table with a JOIN on your data to ensure that all dates are present in your results.
You need three things:
A list of dates.
A left join
Aggregation
So:
select d.dte, min(t.time), max(t.time)
from (select date('2015-02-01') as dte union all
select date('2015-02-02') union all
. .
select date('2015-02-28')
) d left join
t
on d.dte = t.date
group by d.dte
order by d.dte;
Try this
set #is_first_date = 0;
set #temp_start_date = date('2015-02-01');
set #temp_end_date = date('2015-02-28');
select my_dates.date,your_table_name.user_id, MIN(your_table_name.time), MAX(your_table_name.time) from
( select if(#is_first_date , #temp_start_date := DATE_ADD(#temp_start_date, interval 1 day), #temp_start_date) as date,#is_first_date:=#is_first_date+1 as start_date from information_schema.COLUMNS
where #temp_start_date < #temp_end_date limit 0, 31
) my_dates left join your_table_name on
my_dates.date = your_table_name.date
group by my_dates.date
Try This query
SELECT `date`, MIN(`time`) as `IN`, MAX('time') AS `OUT`
FROM `table_name` WHERE month(current_date) = month(`date`)
GROUP BY `date`;

Count() does not return zero MySQL

I am a web developer and tried to search for the solution on a mysql query.I am unable to get the right solution for the count() function to return zero.
The count() function doesnot return zero for all dates.
The query is as below . can anyone help me on this.
SELECT
count(stat_id) as typeSuccess,
device_type as typeName,
YEARWEEK(date_auth) as date
FROM auth_stat
WHERE
AUTH_RESULT = 'SUCCESS' AND
date_auth BETWEEN DATE_SUB(CURDATE(), INTERVAL 6 WEEK) AND CURDATE()
GROUP BY YEARWEEK(date_auth), device_type
ORDER BY YEARWEEK(date_auth)
The query that i tried to form is
select
date_auth,
count(stat_id) as typeSuccess,
device_type as typeName,
YEARWEEK(date_auth) as date
from
(
select #curDate := Date_Add(#curDate, interval 1 day) as MyJoinDate
from
(
select #curDate := CURDATE()
) sqlvars, auth_stat limit 18
) dateAll
LEFT JOIN auth_stat U on dateAll.MyJoinDate = U.date_auth
group by dateAll.MyJoinDate
Actual ouput :
+------------+-------------+
| date | typeSuccess |
+------------+-------------+
| 2015-03-18 | 11 |
+------------+-------------+
Expected Output:
+------------+-------------+
| date | typeSuccess |
+------------+-------------+
| 2015-03-18 | 11 |
| 2015-03-19 | 0 |
| 2015-03-20 | 0 |
+------------+-------------+
I believe all you want to do is just this
SELECT
SUM(AUTH_RESULT='SUCCESS') as numSuccess,
YEARWEEK(date_auth) as date
FROM auth_stat
WHERE date_auth BETWEEN DATE_SUB(CURDATE(), INTERVAL 6 WEEK) AND CURDATE()
GROUP BY YEARWEEK(date_auth), device_type
ORDER BY YEARWEEK(date_auth)
basically all i'm doing is telling MySQL to sum up the boolean value (0 or 1) when auth_result is a success.. SUM() will return a 0 for a particular week if there is no successes in that week
The main issue is you were filtering out all non successful auth_results which would then not be counted. so remove that from the where and you should be good!
if you want it per day then you can do this
SELECT
SUM(AUTH_RESULT='SUCCESS') as numSuccess,
DATE(date_auth) as date
FROM auth_stat
WHERE date_auth BETWEEN DATE_SUB(CURDATE(), INTERVAL 6 WEEK) AND CURDATE()
GROUP BY DATE(date_auth), device_type
ORDER BY DATE(date_auth)
SQLFIDDLE FOR BOTH RESULTS
try
SELECT COUNT(statid), dates.auth_date
FROM
( SELECT DISTINCT auth_date
FROM Table1
WHERE auth_date BETWEEN '2015-03-06' AND '2015-03-09' -- or whatever
) AS dates
LEFT JOIN Table1 ON TRUE
AND Table1.auth_date = dates.auth_date
AND table1.auth_result = 'SUCCESS'
GROUP BY dates.auth_date
ORDER BY dates.auth_date
as desribed here: http://sqlfiddle.com/#!9/84faf/2
for eg data:
+--------+-------------+------------+
| statid | auth_result | auth_date |
+--------+-------------+------------+
| 1 | SUCCESS | 2015-03-05 |
| 2 | SUCCESS | 2015-03-05 |
| 3 | SUCCESS | 2015-03-05 |
| 4 | OTHER | 2015-03-06 |
| 5 | OTHER | 2015-03-06 |
| 6 | OTHER | 2015-03-06 |
| 7 | SUCCESS | 2015-03-07 |
| 8 | SUCCESS | 2015-03-07 |
| 9 | SUCCESS | 2015-03-07 |
| 10 | OTHER | 2015-03-08 |
| 11 | SUCCESS | 2015-03-08 |
| 12 | OTHER | 2015-03-08 |
| 13 | SUCCESS | 2015-03-09 |
| 14 | SUCCESS | 2015-03-09 |
| 15 | SUCCESS | 2015-03-09 |
| 16 | OTHER | 2015-03-10 |
| 17 | OTHER | 2015-03-10 |
| 18 | SUCCESS | 2015-03-10 |
| 19 | OTHER | 2015-03-11 |
+--------+-------------+------------+
eg output:
+---------------+-------------------------+
| count(statid) | auth_date |
+---------------+-------------------------+
| 0 | March, 06 2015 00:00:00 |
| 3 | March, 07 2015 00:00:00 |
| 1 | March, 08 2015 00:00:00 |
| 3 | March, 09 2015 00:00:00 |
+---------------+-------------------------+
It is not beautiful but hope it helps:
SELECT
date_auth,
count(stat_id) as typeSuccess,
device_type as typeName,
YEARWEEK(date_auth) as date
FROM
(
SELECT
DATE(DATE_ADD(NOW(), interval tmp.id day)) AS MyJoinDate
FROM (SELECT 1 as id
UNION ALL SELECT 2
UNION ALL SELECT 3
UNION ALL SELECT 4
UNION ALL SELECT 5
UNION ALL SELECT 6
UNION ALL SELECT 7
UNION ALL SELECT 8
UNION ALL SELECT 9
UNION ALL SELECT 10
UNION ALL SELECT 11
UNION ALL SELECT 12
UNION ALL SELECT 13
UNION ALL SELECT 14
UNION ALL SELECT 15
UNION ALL SELECT 16
UNION ALL SELECT 17
UNION ALL SELECT 18
) AS tmp
) dateAll
LEFT JOIN auth_stat U on dateAll.MyJoinDate = U.date_auth
group by dateAll.MyJoinDate
I have tried adding the query as below. It stills returns me records that have the counts and not the dates with the count as zero.
SELECT COUNT(stat_id), dates.date_auth
FROM
( SELECT DISTINCT date_auth
FROM auth_stat
WHERE date_auth BETWEEN DATE_SUB(CURDATE(), INTERVAL 20 DAY) AND CURDATE()
) AS dates
LEFT JOIN auth_stat ON TRUE
AND auth_stat.date_auth = dates.date_auth
AND auth_stat.auth_result = 'SUCCESS'
GROUP BY dates.date_auth
ORDER BY dates.date_auth
Output result for the above query:
COUNT(stat_id) date_auth Ascending 1
1 2015-03-05 00:00:00
1 2015-03-06 00:00:00
11 2015-03-18 00:00:00

SQL query for Min() and grouping

My Table name is powerpro including data as following
+-----------+-------------------+---------------+
| record_no | date_time | phase1_energy |
+-----------+-------------------+---------------+
| | | |
| 1 | 12/01/14 12:00 AM | 234 |
| 2 | 12/01/14 01:00 AM | 230 |
| 3 | 12/01/14 02:00 AM | 220 |
| 4 | 12/01/14 03:00 AM | 222 |
| 5 | 13/02/14 12:00 AM | 233 |
| 6 | 13/02/14 01:00 AM | 234 |
| 7 | 13/02/14 02:00 AM | 220 |
| 8 | 13/02/14 03:00 AM | 220 |
| 9 | 14/03/14 12:00 AM | 234 |
| 10 | 14/03/14 01:00 AM | 231 |
| 11 | 14/03/14 02:00 AM | 219 |
| 12 | 14/03/14 03:00 AM | 216 |
+-----------+-------------------+---------------+
I want to get phase1_energy balance (from each day minimum reading deducting by next day minimum reading) back to 7 days from NOW()
I tried this:
SELECT a1.* FROM powerpro a1
INNER JOIN
(
select MIN(date_time) as min FROM powerpro
GROUP BY date(date_time)
) a2
ON a1.date_time = a2.min
WHERE date_time BETWEEN DATE_SUB(NOW(), INTERVAL 7 DAY) AND NOW() ORDER BY date_time
But only got the minimum reading of each day as follows.
+-----------+-------------------+---------------+
| record_no | date_time | phase1_energy |
+-----------+-------------------+---------------+
| | | |
| 1 | 12/01/14 12:00 AM | 234 |
| 5 | 12/02/14 12:00 AM | 233 |
| 9 | 12/03/14 12:00 AM | 234 |
+-----------+-------------------+---------------+
Can anyone help me ? Thanks
If I understand correctly, for each date you want the min time (which you managed to get), and the next day's min time.
Here is how you can get that next day min time (EDIT: adding the energy of both days):
SELECT DATE(a1.date_time) AS `date`, a1.date_time AS this_day_min_read, a1.phase1_energy AS this_day_energy,
a4.date_time AS next_day_min_read, a4.phase1_energy AS next_day_energy
FROM powerpro a1
JOIN (SELECT DATE(date_time) `date`, MIN(date_time) AS `min`
FROM powerpro
GROUP BY DATE(date_time)
) a2 ON a1.date_time = a2.min
JOIN (SELECT DATE(date_time) `date`, MIN(date_time) AS `min`
FROM powerpro
GROUP BY DATE(date_time)
) a3 ON DATE(a1.date_time) = a3.date - INTERVAL 1 DAY
JOIN powerpro a4
ON a4.date_time = a3.min
WHERE date_time BETWEEN DATE_SUB(NOW(), INTERVAL 7 DAY) AND NOW()
ORDER BY date_time
Hope this helps.

Select highest value for each foreign key using time interval

I have a database of measurements for different locations that is taken every 1 hour.
ID | LOCATION_ID | CMS | DATE
6 | C | 7 | 2014-11-27 12:00:00
5 | B | 3 | 2014-11-27 12:00:00
4 | A | 19 | 2014-11-27 12:00:00
3 | C | 9 | 2014-11-27 11:00:00
2 | B | 8 | 2014-11-27 11:00:00
1 | A | 11 | 2014-11-27 11:00:00
I need to select the highest cms for each unique location, within the last 3 hours. For example;
ID | LOCATION_ID | CMS | DATE
3 | C | 9 | 2014-11-27 11:00:00
2 | B | 8 | 2014-11-27 11:00:00
4 | A | 19 | 2014-11-27 12:00:00
I am using the below MySQL to return the max, but I am missing the final piece. What do I need to complete the statement?
SELECT MAX(cms) as value_of_rain
FROM `rainfall`
WHERE `date` >= SUBDATE( NOW( ) , INTERVAL 3 HOUR )
You are missing the grouping statement using GROUP BY like
SELECT MAX(cms) as value_of_rain
FROM `rainfall`
WHERE `date` >= SUBDATE( NOW( ) , INTERVAL 10 MINUTE )
GROUP BY LOCATION_ID