Empty table by using NOT EXISTS - mysql

I have a query:
SELECT g.name, s.hour, gs.weekday
FROM schedule s
INNER JOIN group_schedule gs ON gs.schedule_id = s.id
INNER JOIN groups g ON g.id = gs.group_id
WHERE EXISTS (
SELECT *
FROM group_schedule
WHERE group_id =6
)
ORDER BY g.name, gs.weekday
that return:
name hour weekday
A1-A2 10:00:00 1
A1-A2 17:00:00 1
A1-A2 10:30:00 1
A1-A2 17:30:00 1
A1-A2 18:00:00 2
A1-A2 11:30:00 2
A1-A2 18:30:00 2
A1-A2 11:00:00 2
A1-A2 12:30:00 3
But I need too to get rows which don't have these combinations, for example:
name hour weekday
A1-A2 10:30:00 1
A1-A2 11:00:00 1
A1-A2 11:30:00 1
...
If I use NOT EXISTS I obtain an empty table.

I don't know but do you mean something like:
SELECT g.name, s.hour, gs.weekday
FROM schedule s
INNER JOIN group_schedule gs
ON gs.schedule_id = s.id AND group_id = 6
INNER JOIN groups g ON g.id = gs.group_id
ORDER BY g.name, gs.weekday
Moving the group_id condition out of the general WHERE clause and into the group_schedule JOIN? You know can have an arbitrary logical expression following the ON keyword.

Related

Add value from other value with diffrent date in mysql

I have some problem in mysql, I have data like this
id
date
renewaltime
111
2020-01-01
1
111
2020-01-02
1
111
2020-01-03
1
111
2020-01-04
1
111
2020-01-05
1
but I wanna output be like this in mysql
id
date
renewaltime
renewal_by_date
111
2020-01-01
1
1
111
2020-01-02
1
2
111
2020-01-03
1
3
111
2020-01-04
1
4
111
2020-01-05
1
5
adding the value with value before in diffrent datetime
SELECT
h.id as ID,
i.date as DATE,
count(it.relid) as RENEWALTIME
FROM tblhosting h
INNER JOIN tblinvoiceitems it on h.id=it.relid
INNER JOIN tblinvoices i on it.invoiceid=i.id
WHERE h.id =305864
and i.status = 'Paid'
AND it.type = 'Hosting'
AND h.regdate <> it.duedate
GROUP BY i.date
please if you have same problem and share withme
thanks
On MySQL 8+, this is a cinch with analytic functions:
SELECT h.id, i.date,
SUM(COUNT(it.relid)) OVER (ORDER BY i.date) RENEWALTIME
FROM tblhosting h
INNER JOIN tblinvoiceitems it ON h.id = it.relid
INNER JOIN tblinvoices i ON it.invoiceid = i.id
WHERE
h.id = 305864 AND
i.status = 'Paid' AND
it.type = 'Hosting' AND
h.regdate <> it.duedate
GROUP BY
i.date
ORDER BY
i.date;

Show Null Value from 2 comparable records in MySQL

I have example data table from attendance machine system like this:
ID Name In
1 John 2015-04-17 08:00:00
1 John 2015-04-17 16:30:00
1 John 2015-04-20 10:01:00
1 John 2015-04-21 10:00:00
1 John 2015-04-21 19:00:00
Here my query:
SELECT a.id AS ID, a.nama AS `Name`, DATE_FORMAT(a.att, '%d-%b-%y') AS `Date`,
DATE_FORMAT(a.att, '%T') as `IN`, DATE_FORMAT(b.att, '%T') AS `OUT`
FROM attendance a
INNER JOIN attendance b
on date(a.att) = date(b.att) AND a.id = b.id
WHERE b.att > a.att
With above query I can split the In (column) time into 2 column become In and out like this:
Id Name Date In Out
1 John 17-Apr-15 08:00:00 16:30:00
1 John 21-Apr-15 10:00:00 19:00:00
The problem is if user John forget to use finger print where he out, for example on date 20 April, the data is not display. So, I want to my output become like this:
Id Name Date In Out
1 John 17-Apr-15 08:00:00 16:30:00
1 John 20-Apr-15 10:01:00 NULL
1 John 21-Apr-15 10:00:00 19:00:00
You should use a LEFT JOIN instead of an INNER JOIN. Or you can use this query instead:
SELECT
Id,
Name,
DATE(att) AS `Date`,
DATE_FORMAT(MIN(att), '%T') AS `In`,
CASE WHEN MAX(att)<>MIN(att) THEN DATE_FORMAT(MAX(att), '%T') END AS `Out`
FROM
attendance
GROUP BY
Id, Name, DATE(att)
Please see a fiddle here.

MySQL LEFT JOIN dates with order

I have a following tables:
sensors:
id name key code
1 s1 abc 123
2 s2 def 456
3 s3 ghi 789
measurements:
id value sensor_id generated_at
1 1.0 1 2013-12-30 06:00:00
2 1.0 1 2013-12-30 06:01:00
3 1.0 1 2013-12-30 06:02:00
4 3.0 2 2013-12-30 07:00:00
5 3.0 2 2013-12-30 07:01:00
6 3.0 2 2013-12-30 07:05:00
7 5.0 3 2013-12-30 08:02:00
8 5.0 3 2013-12-30 08:03:00
9 5.0 3 2013-12-30 08:11:00
10 5.0 3 2013-12-30 08:15:00
What I want to do is to generate report with all sensors data and include first and last generated_at time for received measurements, so the result of MySQL request should look like:
id name key code first_value_generated_at last_value_generated_at
1 s1 abc 123 2013-12-30 06:00:00 2013-12-30 06:02:00
2 s2 def 456 2013-12-30 07:00:00 2013-12-30 07:05:00
3 s3 ghi 789 2013-12-30 08:02:00 2013-12-30 08:15:00
I would appreciate any help, thanks.
I don't think that LEFT JOIN is really necessary here (only in case when there more or less sensors.id than in measurements.sensor_id). SQL query is below :
SELECT
s.id,
s.name,
s.key,
s.code,
m.first_value_generated_at,
m.last_value_generated_at
FROM sensors s JOIN
(SELECT
sensor_id,
MIN(generated_at) as first_value_generated_at,
MAX(generated_at) as last_value_generated_at
FROM
measurements
GROUP BY
sensor_id
) m ON s.id = m.sensor_id
ORDER BY
s.id
I hope this should work for you,
select *
,(select min(generated_at) from measurements as a where a.sensor_id =s.id) as first_value_generated_at
,(select max(generated_at) from measurements as b where b.sensor_id =s.id) as last_value_generated_at
from sensors as s
Try this query , it will generate the exact output you need
select s.id,s.name,s.key,s.code,min(m.generated_at) first_vaue_generated_at,max(m.generated_at) last_value_generated_at
from sensors s
LEFT JOIN measurements m ON (s.id = m.sensor_id)
group by 1,2,3,4;
Try this it will work
select s.id,s.name,s.key,s.code,m.generated_at as first_value_generated_at,ml.generated_at as last_value_generated_at from sensors as s,measurements as mf,measurements as ml where s.id = mf.sessor_id and s.id = ml.sensor_id and mf.generated_at < ml.generated_at group by mf.sensor_id
Maybe this could do that - nested selects?
select sensors.id, sensors.name, sensors.key, sensors.code,
( select generated_at from measurements order by time asc limit 1 )
as first_value_generated_at,
( select generated_at from measurements order by time desc limit 1 )
as last_value_generated_at from sensors

Select last entry for every user from log table

Hello I have problem with sql that is suppose to select last log entry per user for many users.
This is sample how my table looks like
user_id | date
--------------------
1 2013-03-06 10:00:00
17 2013-03-06 11:00:00
2 2013-03-06 10:00:00
5 2013-03-06 10:00:00
1 2013-03-06 11:00:00
17 2013-03-06 13:00:00
17 2013-03-06 13:01:00
2 2013-03-06 14:01:00
2 2013-03-06 15:00:00
2 2013-03-06 18:01:00
The result of this query is suppose to be
user_id | date
--------------------
1 2013-03-06 11:00:00
2 2013-03-06 18:01:00
5 2013-03-06 10:00:00
17 2013-03-06 13:01:00
For now I'm using this query
SELECT
a.user_id,
(SELECT b.date FROM alerts.alerts_log as b WHERE b.user_id = a.user_id ORDER BY b.date DESC LIMIT 1) as date
FROM
alerts.alerts_log as a
WHERE
a.user_id IN (1,2,5,17)
GROUP BY a.user_id
but I dont thiknk its the best one because will be too slow for many records...
can you pls suggest me better one
SELECT user_id , MAX(date)
FROM alerts.alerts_log
GROUP BY user_id;
if you have only two columns in the table, the query below will suffice your needs,
SELECT user_ID, MAX(date) max_date
FROM tableName
GROUP BY user_ID
SQLFiddle Demo
but if not and you want to get all columns within the row, you need to have subquery which separately gets the maximum date per user_ID.
SELECT a.*
FROM tableName a
INNER JOIN
(
SELECT user_ID, MAX(date) max_date
FROM tableName
GROUP BY user_ID
) b ON a.user_ID = b.user_ID AND
a.date = b.max_date
SQLFiddle Demo

how to use joins in my sql?

there are two tables tbldoctor and tblschedule
tbldoctor
doc_id(PK) docMrId docfname
1 22 manish
2 23 rahul
3 22 ashish
4 24 ahemad
5 22 narendra
6 22 akshat
tblschedule
doctor_id(FK) mr_id schedule_date
1 22 2012-06-12
1 22 2012-06-13
3 22 2012-06-14
3 22 2012-06-14
4 24 2012-06-12
4 24 2012-06-12
5 22 2012-06-14
5 22 2012-06-15
5 22 2012-06-12
What i want is list of all doctorid and the count of particular doctor repeated in tblschedule table where schedule_date parameter and mr_id is provided here we are supposed mr_id =22 and schedule_date between 2012-06-01 to 2012-06-31
Output Should look like
doc_id docfname count
1 manish 2
3 rahul 2
5 narendra 3
6 akshat 0
select d.doc_id, docfname, count(mr_id) as count
from tbldoctor d
left outer join tblschedule s on s.doctor_id = d.doc_id
where mr_id = 22
and schedule_date between '2012-06-01' and '2012-06-31'
group by s.doctor_id
edit
select d.doc_id,
docfname,
sum(case when mr_id = 22
then 1
else 0
end) as count
from tbldoctor d
left outer join tblschedule s on s.doctor_id = d.doc_id
and schedule_date between '2012-06-01' and '2012-06-31'
group by s.doctor_id
SQLFiddle example
edit 2
how about
select d.doc_id, docfname, count(mr_id) as count
from tbldoctor d
left outer join tblschedule s on s.doctor_id = d.doc_id and mr_id = docmrid
where docmrid = 22
and (schedule_date between '2012-06-01' and '2012-06-31' or mr_id is null)
group by s.doctor_id
order by d.doc_id
SQLFiddle example
Not 100% sure I've understood you, but this will give you a list of all doctor IDs, along with the number of schedule items for each in between two given dates.
SELECT tbldoctor.doc_id, COUNT(*) cnt
FROM tbldoctor d INNER JOIN tblschedule s
ON d.doc_id = s.doctor_id
WHERE s.schedule_date BETWEEN '2012-06-12' AND '2012-06-15'
GROUP BY tbldoctor.doc_id
SELECT * FROM `tbldoctor` JOIN `tblschedule` ON `tblschedule`.doctor_id(FK) = `tbldoctor`.doc_id(PK)
SELECT tbldoctor.doc_id, COUNT(*) cnt FROM tbldoctor d INNER JOIN tblschedule s ON d.doc_id = s.doctor_id WHERE s.schedule_date BETWEEN '2012-06-12' AND '2012-06-15' GROUP BY tbldoctor.doc_id