I have the following table:
oDate oTime oAct
--------------------------------------
2017-06-01 00:00:00 A
2017-06-01 01:00:00 B
2017-06-01 02:00:00 C
ff.
2017-06-02 00:00:00 B
ff.
I want to select a day before (only after 21:00:00) and after.
Let say, If I Select '2017-06-02' then the result should be:
oDate oTime oAct
--------------------------------------
2017-06-01 22:00:00 A
2017-06-02 00:00:00 B
2017-06-02 01:00:00 C
ff.
2017-06-03 00:00:00 C
ff.
Also, for the query. I only have one parameter, which is #oDate date.
Please advise.
Thank you.
If I follow your question correctly I think you are after a where clause such as this:
select
*
from YourTable
where (
oDate > '20170602'
OR
(oDate = '20170602' AND oTime >= '21:00:00')
)
This would give you all dates after 2017-06-02 as well as times on that date at and after 21:00
To make best use of indexes that may exist on those columns I suggest you do not try to combine the date with time such as this dateadd(day,datediff(day,0,oDate),oTime) and then try to filter >= '20170602 21:00:00' as that would produce table scanning.
perhaps this will help
select
*
from YourTable
where (
oDate > #dateparameterhere
OR
(oDate = #dateparemterhere AND oTime >= '21:00:00')
)
Try this
concatenating fields to make a datetime field
select
* from table
where
cast (cast(odate as varchar(max)) + ' ' + cast(otime as varchar(max)) as datetime) < cast('2017-06-02 21:00:00' as datetime)
Related
I have the following table:
Group RecDate oData
---------------------------------------
123 2022-03-20 02:00:00 F1xR
123 2022-03-21 02:30:00 F1xF
123 2022-03-22 05:00:00 F1xN
123 2022-03-15 04:00:00 F2xR
From the table above, I want to get the MAX date group by 2 char from oData field. Then I wrote a query like this:
SELECT a.Group, MAX(a.RecDate) RecDate, LEFT(a.oData, 2) oDataNo
INTO #t1
FROM TableData a
GROUP BY a.Group, LEFT(a.oData, 2)
SELECT * FROM #t1
Then, the result should be:
Group RecDate oDataNo
--------------------------------------------
123 2022-03-22 05:00:00 F1
123 2022-03-15 04:00:00 F2
From the result above (#t1), I want to join with the TableData to get the RIGHT character (1 digit) from oData field. So I INNER JOIN the #t1 with TableData. The JOIN field is RecDate. But it is strange that the result isn't what I want.
The query like:
SELECT RIGHT(a.oData,1) oDataStat, b.*
FROM TableData a
INNER JOIN #t1 b ON a.RecDate = b.RecDate
The wrong result like:
The result should be:
Group RecDate oDataNo oDataStat
-----------------------------------------------------------
123 2022-03-22 05:00:00 F1 N
123 2022-03-15 04:00:00 F2 R
Am I doing wrong approach?
Please advise. Really appreciated.
Thank you.
The query you provided returns the data you desire. However its cleaner to do it in a single query e.g.
WITH cte AS (
SELECT *
, RIGHT(a.oData,1) oDataStat
, ROW_NUMBER() OVER (PARTITION BY LEFT(a.oData, 2) ORDER BY RecDate DESC) rn
FROM TableData a
)
SELECT [Group], RecDate, oData, oDataStat
FROM cte
WHERE rn = 1
ORDER BY RecDate;
returns:
Group
RecDate
oData
oDataStat
123
2022-03-15 04:00:00
F2xR
R
123
2022-03-22 05:00:00
F1xN
N
Note: Your query as posted doesn't actually run due to not escaping [Group] - you should ensure everything you post has any errors removed first.
At the end of an enormous stored procedure (in SQL Server), I've created two CTE. One with some date ranges (with 6 month intervals) and one with some records.
Let's assume i have date ranges on table B from 2020-01-01 to 2010-01-01 (with 6 months intervals)
Start End
----------------------
2020-01-01 | 2020-07-01
... ...
other years here
... ...
2010-01-01 | 2010-07-01
and on table A this situation:
Name Date
-----------------
John 2020-01-01
John 2019-01-01
John 2018-07-01
... ...
Rob 2020-01-01
Rob 2019-07-01
Rob 2018-07-01
... ...
I'm trying to generate a recordset like this:
Name MissingDate
-----------------
John 2019-07-01
... ...
John 2010-01-01
Rob 2019-01-01
... ...
Rob 2010-01-01
I've got the flu and I barely know who I am at this moment, I hope it was clear and if anyone could help me with this I would really appreciate it.
If you want missing dates (which appear to be by month), then generate all available dates and take out the ones you have.
with cte as (
select start, end
from dateranges
union all
select dateadd(month, 1, start), end
from cte
where start < end
)
select n.name, cte.start
from cte cross join
(select distinct name from tablea) n left join
tablea a
on a.date = cte.start and a.name = n.name
where a.date is null;
Below is my sql query to get the list of dates from a table.
select t2.counter_date as myDates from table1 t1;
output:
myDates
2014-03-14 00:00:00
2014-05-11 00:00:00
2014-11-03 00:00:00
2014-12-23 00:00:00
2015-01-12 00:00:00
2015-08-08 00:00:00
2016-03-14 00:00:00
2017-03-14 00:00:00
2017-03-19 00:00:00
Below is the solution:
select min(t1.counter_date) as oldDate,max(t1.counter_date) as latestDate from table1 t1;
In the following demo you can see that your query is giving the correct results. The problem must be in your data.
EDIT: after the edit it is clear where the problem is. Once you perform the following query:
SELECT min(date), max(date)
FROM tab
GROUP BY date
than min(date) has to be equal to max(date) since there is just one date in the group.
I have a DB which looks like this :
FromDate ToDate ProfileUID
2017-02-10 07:00:00 2017-02-10 15:30:00 TB_D
2017-02-09 23:00:00 2017-02-10 07:00:00 ZK_D
2017-02-09 17:30:00 2017-02-09 23:00:00 DL_D
2017-02-09 07:00:00 2017-02-09 17:30:00 AM_D
2017-02-08 23:00:00 2017-02-09 07:00:00 CK_D
2017-02-08 17:30:00 2017-02-08 23:00:00 DJ_N
This DB is often modified manually and some errors can be done by user.
I'm trying to do an SQL query to check if the schedule is ok, which means I would like to know until when my records are (here we filled only for the two next days) and if there are no "black holes" in the schedule, meaning there is a period with no profileUID filled.
What I have so far :
SELECT *,LAG (ToDate) OVER (PARTITION BY FromDate ORDER BY FromDate)
FROM `dashboardcalendar`
WHERE FromDate>= NOW()
ORDER BY `dashboardcalendar`.`FromDate` ASC
EDIT: Given that you can't use window functions on your version of MariaDB, try this:
SELECT FromDate, ToDate, ProfileUID, next_FromDate, last_ToDate,
CASE WHEN next_record_uid is null then 'Warning - Gap after' end warn1,
CASE WHEN prev_record_uid is null then 'Warning - Gap before' end warn2
FROM (
SELECT t1.FromDate, t1.ToDate, t1.ProfileUID,
t2.ProfileUID next_record_uid,
t3.ProfileUID prev_record_uid
FROM table t1
LEFT JOIN table t2
ON t1.ToDate = t2.FromDate
LEFT JOIN table t3
ON t1.FromDate = t3.ToDate
)
This does not account for overlaps in time - it will give a false positive warning if two time periods overlap.
Original answer:
I'd use LEAD as well as LAG, and then wrap in another select to do the comparison:
SELECT FromDate, ToDate, ProfileUID, next_FromDate, last_ToDate,
CASE WHEN ToDate < next_FromDate then 'Warning - Gap after' end warn1,
CASE WHEN FromDate > last_ToDate then 'Warning - Gap before' end warn2
FROM (
SELECT FromDate, ToDate, ProfileUID,
LEAD(FromDate,1) OVER (ORDER BY FromDate) next_FromDate,
LAG(FromDate,1) OVER (ORDER BY FromDate) last_ToDate
FROM table
)
You should not need to partition, it sounds like from your description that each record covers a distinct period of time so there's nothing to group on.
Each row has a BookedMonth and a ReportingMonth. I want to return the rows where the ReportingMonth is 2 Months greater than the BookedMonth.
ReportingMonth BookedMonth
2016-01-01 00:00:00 2015-11-01 00:00:00
2016-01-01 00:00:00 2015-12-01 00:00:00
2016-01-01 00:00:00 2016-01-01 00:00:00
WHERE
DATEDIFF,BookedMonth,ReportingMonth,2
Something like:
select * from table where datediff(month, ReportingMonth, BookedMonth) > 2;
EDIT
Or better... se comments here below:
select * from table where ReportingMonth > dateadd(month, 2, BookedMonth);