Get sql data if have a specific value - mysql

I have this table :
id device createdAt type
1 700 2018-09-06 10:00:00 atos
2 700 2018-09-06 09:30:00 farkos
The idea is to verify if in last x hours I have in this table only data type = atos.
For that case I want to get a false as result. If this table will have only type = atos in last h hours the result expected should be true.
I tried like this and after that check with php but not very good idea (I want to do that in sql only) whitout additional treatment :
SELECT * FROM table t
WHERE t.device = 700
AND t.createdAt >= '2018-09-05 11:00:00'

This query will do what you want. It looks at all the entries in the time specified and if any of them is not atos, will return 0 (false). Otherwise it will return 1 (true).
SELECT MIN(CASE WHEN t.type != 'atos' THEN 0 ELSE 1 END)
FROM table1 t
WHERE t.device = 700 AND t.createdAt >= '2018-09-05 11:00:00'
If you want to check for the last h hours, change the WHERE clause to
WHERE t.device = 700 AND t.createdAt >= NOW() - INTERVAL h HOUR

Use case when:
SELECT deviceid,case when min(case when type='atos' then 1 else 0 end)=0 then false when min(case when type='atos' then 1 else 0 end)=1 then true end as val FROM table
t
WHERE t.device = 700
AND t.createdAt >= '2018-09-05 11:00:00'
group by deviceid

Related

sql filter by condition but result show everything

Having this table
trans_date | settle_date | type
2022-06-08 | 2022-06-09 | In
2022-06-08 | 2022-06-09 | In
2022-06-08 | | Out
2022-06-09 | | Out
I want to only select:
If type is In, use settle_date
If type is Out, use trans_date
I am doing this:
SELECT *
FROM tx
WHERE DATE(CASE WHEN tx.type= 'IN'
THEN tx.settle_date
ELSE tx.trans_date END) <= '2022-06-08' .
OR DATE(CASE WHEN tx.type = 'IN'
THEN tx.settle_date
ELSE tx.trans_date END) <= '2022-06-09'
but everything is select out, I expected the last row to be excluded.
I want IN to use <= 2022-06-09 and OUT to use <= 2022-06-08
You're only choosing the column in the CASE expression, not the dates to compare with. Then you're selecting a row if that column is less than either of the dates, because of the OR condition.
Put the whole comparison in the CASE expression, not just the column name.
SELECT *
FROM tx
WHERE CASE tx.type
WHEN 'IN' THEN tx.settle_date <= '2022-06-09'
ELSE tx.trans_date <= '2022-06-08'
END
DEMO
You said "..I expected the last row to be excluded.", which I assume is your expected result.. so could you perhaps mean something like this:
SELECT *,
CASE WHEN tx.type= 'In'
AND tx.settle_date <= '2022-06-09'
THEN tx.settle_date
WHEN tx.type= 'Out'
AND tx.trans_date <= '2022-06-08'
THEN tx.trans_date END AS f_date
FROM tx
HAVING f_date IS NOT NULL
Instead of doing WHERE, you probably want to do it in SELECT then filter the result afterward.
Demo fiddle

Display all data grouped by date in a particular timeframe

Currently I have 2 tables, a listing table and a logs table. With the following query I'm trying to get the listings of a product on a particular day, and it returns the right output.
with X as (
select
l.*,
(select status_from from logs where logs.refno = l.refno and logs.logtime >= '2021-10-01' order by logs.logtime limit 1) logstat
from listings l
where l.added_date < '2021-10-01'
)
, Y as (select X.*, ifnull(X.logstat, X.status) stat from X)
SELECT
status.text,
COUNT(Y.id) AS c
from status
left join Y on Y.stat = status.code
group by status.code, status.text;
This gives an output like this:
Here I've filtered the query by 1 date which in this case is 2021-10-01. Now I have 2 input forms where the user can select a from date and a to date. So I want to be able to get all the data between the date range provided. So basically if I choose a date between 2021-10-01 and 2021-10-02, it should show everything on and between that date. The output should look like:
Date
Publish
Action
Let
Sold
Draft
2021-10-01
0
3
0
1
1
2021-10-02
0
2
0
1
2
Dbfiddle: https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=5e0b8d484a41ac9104d0fb002e7f9a3c
I've formatted the table to show the entries in a row wise manner with the following query:
with X as (
select l.*,
(select status_from from logs where logs.refno = l.refno and logs.logtime >= '2021-10-01' order by logs.logtime limit 1) logstat
from listings l
where l.added_date < '2021-10-01'
)
, Y as (select X.*, ifnull(X.logstat, X.status) stat20211001 from X)
SELECT
sum(case when status.text= 'Action' and Y.id is not null then 1 else 0 end) as `Action`,
sum(case when status.text= 'Draft' and Y.id is not null then 1 else 0 end) as `Draft`,
sum(case when status.text= 'Let' and Y.id is not null then 1 else 0 end) as `Let`,
sum(case when status.text= 'Sold' and Y.id is not null then 1 else 0 end) as `Sold`,
sum(case when status.text= 'Publish' and Y.id is not null then 1 else 0 end) as `Publish`
from status
left join Y on Y.stat20211001 = status.code
Output for this statement:
If you open my dbfiddle and enter date as 2021-10-01 it gives correct output and if you enter 2021-10-02 it shows correct output. Now I just want a way to show these both together. Also if it is suppose 2021-10-01 and 2021-10-05, it should show everything in middle too which means 2021-10-01, 2021-10-02, 2021-10-03, 2021-10-04 and 2021-10-05
Your listings.added_date column has the DATETIME data type. Therefore, to select a date range of 2021-10-01 to 2021-10-02 you need to do this.
WHERE added_date >= '2021-10-01'
AND added_date < '2021-10-02' + INTERVAL 1 DAY
This pulls in all the rows from midnight on 1-October, up to but not including midnight on 3-October.
If you want to aggregate your results by day, you can use GROUP BY DATE(added_date).
A sample query -- to show all days in September -- might look like this:
SELECT DATE(added_date) day,
SUM(CASE WHEN status.text= 'Action' THEN 1 ELSE 0 END) AS `Action`,
SUM(CASE WHEN status.text= 'Draft' THEN 1 ELSE 0 END) AS `Draft`,
SUM(CASE WHEN status.text= 'Let' THEN 1 ELSE 0 END) AS `Let`
FROM tbl
WHERE added_date >= '2021-09-01'
AND added_date < '2021-09-01' + INTERVAL 1 MONTH
GROUP BY DATE(added_date);
Sorry to say, I don't understand how your sample query works well enough to rewrite it with GROUP BY. But this should get you started.

Grouping based on current timestamp in sql

Okay So I have a df like this:
MEETING_ID sSTART
322 2021-05-01 23:45:00.000
322 2021-05-03 13:45:00.000
312 2021-05-11 23:45:00.000
312 2021-05-13 23:45:00.000
And all I want is a table that can tell me how many previous meetings have occurred and how many meetings are coming up...
To do this I use the CURRENT_TIMESTAMP function, unsure if this is wrong but here's my query that isnt working... For the purposes of this post let's say current time is 5/2/2021 10:40PM
WITH s AS (
SELECT MEETING_ID,
CASE WHEN sSTART > CURRENT_TIMESTAMP THEN 1
ELSE 0
END PREVIOUS_MEETING,
CASE WHEN sSTART < CURRENT_TIMESTAMP THEN 1
ELSE 0
END UPCOMING_MEETING
FROM df
),
ddd AS (SELECT
MEETING_ID,
COUNT(PREVIOUS_MEETING),
COUNT(UPCOMING_MEETING)
FROM s
GROUP BY MEETING_ID
)
SELECT *
FROM ddd
In the end I want this:
MEETING_ID PREVIOUS_MEETING UPCOMING_MEETING
322 1 1
312 2 0
I'm unsure why this is the case but some explanation would help.
You just want a basic pivot query here:
SELECT
MEETING_ID,
SUM(sSTART > CURRENT_TIMESTAMP) AS PREVIOUS_MEETING,
SUM(sSTART <= CURRENT_TIMESTAMP) AS CURRENT_MEETING
FROM df
GROUP BY
MEETING_ID;
Note that we are summing boolean expressions above, which is valid syntax in MySQL. On other databases, you might have to take conditional counts, something like this:
SELECT
MEETING_ID,
COUNT(CASE WHEN sSTART > CURRENT_TIMESTAMP THEN 1 END) AS PREVIOUS_MEETING,
COUNT(CASE WHEN sSTART <= CURRENT_TIMESTAMP THEN 1 END) AS CURRENT_MEETING
FROM df
GROUP BY
MEETING_ID;

how to get single result in using 2 table data

i have to table 2 in same structure .i already get the result by using one table using following query
SELECT *,COUNT(Time),
CASE WHEN COUNT(Time) = 1
THEN CASE WHEN Time > '00:00:00' && Time <= '12:15:00'
THEN Time END ELSE MIN(Time)
END as time_in,
CASE WHEN COUNT(Time) = 1
THEN CASE WHEN Time > '12:15:00' && Time <= '23:59:59'
THEN Time END ELSE NULLIF(MAX(Time), MIN(Time))
END as time_out
FROM attendancedata
INNER JOIN nonacadamic
ON attendancedata.EnrolledID = nonacadamic.emp_id
WHERE nonacadamic.emp_id = '".$_POST["emp_id"]."' AND Date LIKE '$currentMonth%'
GROUP BY EnrolledID,Date
this query will time devide in to the 2 part(time in and time out) .it work fine.now want to get the data from anther table also.it also have same structure attendancedata table.
attendancedata table structure
EnrolledID Date Time
23 2019-09-09 16:19:00
53 2019-08-27 08:19:00
tempattendancedata table structure
EnrolledID Date Time
23 2019-09-09 16:19:00
23 2019-09-20 08:19:00
i want get the result consider above table record and then split time in to the two part .how can i do this task? actual requirement is tempattendancedata table data also need considering for the time split
you include the results of your temp table using UNION ALL then, put it in a subquery for your select case statement
SELECT *,COUNT(Time)
,CASE WHEN COUNT(Time) = 1 THEN
CASE WHEN Time > '00:00:00' && Time <= '12:15:00'
THEN Time END ELSE MIN(Time)
END as time_in,
CASE WHEN COUNT(Time) = 1 THEN
CASE WHEN Time > '12:15:00' && Time <= '23:59:59'
THEN Time END ELSE NULLIF(MAX(Time), MIN(Time))
END as time_out
FROM
(SELECT *
FROM attendancedata
INNER JOIN nonacadamic
ON attendancedata.EnrolledID = nonacadamic.emp_id
WHERE nonacadamic.emp_id = '".$_POST["emp_id"]."' AND Date LIKE '$currentMonth%'
UNION ALL
SELECT *
FROM tempattendancedata
INNER JOIN nonacadamic
ON attendancedata.EnrolledID = nonacadamic.emp_id
WHERE nonacadamic.emp_id = '".$_POST["emp_id"]."' AND Date LIKE '$currentMonth%') t1
GROUP BY t1.EnrolledID, t1.Date

count user from different districts by selected age

I am trying to write mysql query that would get me the data about the count of users in my different districts by some selcted age .
for example : if i choose age 0-14 i want to get how many users from 'north' ,'south' and etc are between age 0 and 14.
i'm writing the current query :
SELECT sum(case when districts.`districtId` = 1 then 1 else 0 end) as 'North',
sum(case when districts.`districtId` = 4 then 1 else 0 end) as 'Center',
sum(case when districts.`districtId` = 6 then 1 else 0 end) as 'South', , (DATE_FORMAT(NOW(), '%Y') - DATE_FORMAT(userDetails.birthDate2, '%Y') - (DATE_FORMAT(NOW(), '00-%m-%d') < DATE_FORMAT(userDetails.birthDate2, '00-%m-%d'))) as age
from .... where age between 0 and 14
but i get the error : unknown age column.
is there other way to write this query ?!
Try
SELECT districts.districtId, count(userDetails.*)
FROM userDetails, districts
INNER JOIN districts ON userDetails.districtId = districts.districtId
WHERE userDetails.birthDate2 >= (DATE_SUB(NOW(), INTERVAL 14 YEAR)
AND userDetails.birthDate2 <= (DATE_SUB(NOW(), INTERVAL 0 YEAR)
GROUP BY districts.districtId
And for your other question, try to post the database schema..
EDIT :
I Forgotten the GROUP BY Clausse
Since you don't give the full query, try this, filling in with your values :
Select districts.districtId, count(*) as DistrictwiseCount From ... Where age_criterion_goes_here
Group By districts.districtId