Im a beginner with SQL and need help to get some transactions in our WMS between 00.00.00 and 06.00.00 but can't make it work.
This is how far I have come,
SELECT cast(datreg as time) [time], logguser, l16lcode, partno, l16qty, datreg
FROM L16T3
WHERE datreg > '0000-00-00 00:00:00'
AND datreg < '9999-99-99 06:00:00'
AND L16T3.l16lcode = 2
I dont know what to write to get transactions only between 24.00-06.00
(Using SQL Server 2012)
Best Regards
Try this condition:
WHERE DATEPART(hour, datreg) BETWEEN 0 AND 5 OR
(DATEPART(hour, datreg) = 6 AND DATEPART(minute, datreg) = 0 AND DATEPART(second, datreg) = 0)
I would suggest:
SELECT cast(datreg as time) as [time], logguser, l16lcode, partno, l16qty, datreg
FROM L16T3 l
WHERE CONVERT(time, l.datreg) >= '00:00:00' AND
CONVERT(time, l.datreg) < '06:00:00' AND
l.l16lcode = 2;
You can also use the hours:
WHERE DATEPART(hour, l.datreg) >= 0 AND
DATEPART(hour, l.datreg) < 6 AND
l.l16lcode = 2;
However, this does not generalize so easily if, say, the second time were 06:30:00.
Something lie this perhaps:
SELECT IIF(CONVERT(TIME, GETDATE()) BETWEEN '00:00:00' AND '23:59:59','TRUE','FALSE');
Try the above query in SQLFiddle
In your case it would be something like this:
SELECT cast(datreg as time) [time], logguser, l16lcode, partno, l16qty, datreg
FROM L16T3
WHERE CONVERT(TIME, datreg ) BETWEEN '00:00:00' AND '06:00:00'
AND L16T3.l16lcode = 2
Related
I have a database that contains Event data. These Events represent a warning state in a system. They have a StartTime, EndTime, Duration (in seconds) and VarName (and some other attributes that are less relevant for the question).
I am trying to write a query that will allow me to represent the amount of time that a certain warning was active per day. This way, service engineers can easily see if certain changes/fixes caused a warning to decrease or disappear over time.
A quick-and-dirty first attempt is shown below.
SELECT
[VarName] AS metric,
SUM([Duration]) AS value,
Convert(date, [StartTime]) AS date
FROM [dbo].[Events]
WHERE VarName LIKE 'WARN%'
GROUP BY Convert(date, [StartTime]), VarName
ORDER BY date
This works well enough when Events last only a short time and handles multiple Events of the same type in a day. But it breaks down when Events span multiple days (or even weeks).
Example:
VarName
StartTime
EndTime
Duration
WARN_1
2021-06-28 23:00:00.000
2021-06-29 02:00:00.00
10800
What I get:
metric
date
value
WARN_1
2021-06-28
10800
What I want:
metric
date
value
WARN_1
2021-06-28
3600
WARN_1
2021-06-29
7200
Taking into account that:
An event can occur multiple times in the same day
An event can span multiple days
I'll be fiddling with this today and if I come up with a working solution I'll append it to this post. But I don't work with SQL all that often, and it feels like this may require some more advanced trickery. Any help is appreciated!
You can use a recursive CTE to break the periods into days:
with cte as (
select varname, starttime,
(case when datediff(day, starttime, endtime) = 0
then endtime
else dateadd(day, 1, convert(date, starttime))
end) as day_endtime,
endtime
from t
union all
select varname, day_endtime,
(case when datediff(day, starttime, endtime) = 1
then endtime
else dateadd(day, 1, convert(date, day_endtime))
end) as day_endtime,
endtime
from cte
where datediff(day, starttime, endtime) > 0
)
select *
from cte;
To aggregate, change the last part to:
select varname, convert(date, starttime),
sum(datediff(second, starttime, day_endtime))
from cte
group by varname, convert(date, starttime);
Here is a db<>fiddle.
If you need timespans longer than 100 days, add option (maxrecursion 0) or any number larger than about 732.
If you have a numbers table, you can join to that based on the difference in days which will give you n number of rows for each event based on the days. You then just need to calculate how much of each event falls in that day, which I've done with a case expression:
SELECT t.VarName,
StartDate = CONVERT(DATE, DATEADD(DAY, n.Number, t.StartTime)),
Duration = CASE -- starts and ends on same date
WHEN CONVERT(DATE, t.StartTime) = CONVERT(DATE, t.EndTime) THEN t.Duration
-- First Day
WHEN n.Number = 0 THEN DATEDIFF(SECOND, t.StartTime, CONVERT(DATE, DATEADD(DAY, 1, t.StartTime)))
--Last Day
WHEN CONVERT(DATE, DATEADD(DAY, n.Number, t.StartTime)) = CONVERT(DATE, t.EndTime)
THEN DATEDIFF(SECOND, CONVERT(DATE, DATEADD(DAY, n.Number, t.StartTime)), t.EndTime)
-- Middle Day
ELSE 86400
END
FROM #t AS t
INNER JOIN Numbers AS n
ON n.Number <= DATEDIFF(DAY, t.StartTime, t.EndTime);
If you don't have a numbers table, you can very easily create this on the fly:
DECLARE #T TABLE (VarName VARCHAR(10), StartTime DATETIME, EndTime DATETIME, Duration AS DATEDIFF(SECOND, StartTime, EndTime));
INSERT #T (VarName, StartTime, EndTime)
VALUES
('WARN_1', '20210628 23:00:00.000', '20210629 02:00:00.00'),
('WARN_2', '20210629 11:00:00.000', '20210629 14:00:00.00'),
('WARN_3', '20210630 23:00:00.000', '20210704 02:00:00.00');
-- This will do numbers 0-99, add more cross joins if necessary
WITH Numbers (Number) AS
( SELECT ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) - 1
FROM (VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) n1 (N)
CROSS JOIN (VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) n2 (N)
)
SELECT t.VarName,
StartDate = CONVERT(DATE, DATEADD(DAY, n.Number, t.StartTime)),
Duration = CASE -- starts and ends on same date
WHEN CONVERT(DATE, t.StartTime) = CONVERT(DATE, t.EndTime) THEN t.Duration
-- First Day
WHEN n.Number = 0 THEN DATEDIFF(SECOND, t.StartTime, CONVERT(DATE, DATEADD(DAY, 1, t.StartTime)))
--Last Day
WHEN CONVERT(DATE, DATEADD(DAY, n.Number, t.StartTime)) = CONVERT(DATE, t.EndTime)
THEN DATEDIFF(SECOND, CONVERT(DATE, DATEADD(DAY, n.Number, t.StartTime)), t.EndTime)
-- Middle Day
ELSE 86400
END
FROM #t AS t
INNER JOIN Numbers AS n
ON n.Number <= DATEDIFF(DAY, t.StartTime, t.EndTime);
I'm trying to design a view and apply several conditions on my timestamp (datetime): last date and last date minus 7 days.
This works fine for the last date:
SELECT *
FROM table
WHERE timestamp = (SELECT MAX(timestamp) FROM table)
I couldn't figure out the way to add minus 7 days so far.
I tried, for instance
SELECT *
FROM table
WHERE (timestamp = (SELECT MAX(timestamp) FROM table)) OR (timestamp = (SELECT DATEADD(DAY, -7, MAX(timestamp)) FROM table)
and some other variations, including GETDATE() instead of MAX, however, I'm getting the execution timeout messages.
Please let me know what logic should I follow in this case.
Data looks like this, but there's more of it :)
So I want to get data only for rows with 29/11/2019 and 22/11/2019. I have an additional requirement for filtering for factors, but it's a simple one.
If you care about dates, then perhaps you want:
select t.*
from t cross join
(select max(timestamp) as max_timestamp from t) tt
where (t.timestamp >= convert(date, max_timestamp) and
t.timestamp < dateadd(day, 1, convert(date, max_timestamp))
) or
(t.timestamp >= dateadd(day, -7, convert(date, max_timestamp)) and
t.timestamp < dateadd(day, -6, convert(date, max_timestamp))
);
So I ended up with the next code:
SELECT *
FROM table
WHERE (timestamp >= CAST(DATEADD(DAY, - 1, GETDATE()) AS datetime)) AND (timestamp < CAST(GETDATE() AS DATETIME)) OR
(timestamp >= CAST(DATEADD(DAY, - 8, GETDATE()) AS datetime)) AND (timestamp < CAST(DATEADD(day, - 7, GETDATE()) AS DATETIME)) AND (Factor1 = 'Criteria1' OR
Factor2 = 'Criteria2')
Not sure if it's the best or the most elegant solution, but it works for me.
Hi i have been trying to put an SQL query together to pull data from 20:00 last night to 8 am today
what i currntly have is however this only selects between 20:00 and 24 because it's only selecting last night what would be the best way to get the results i am looking for?
SELECT COUNT(CardID) AS CardCOUNT
FROM ReaderData
WHERE (controllerID = 28) AND (ReaderTime BETWEEN '20:00:00' AND '08:00:00') AND (CardID = 'fffffff0') AND (DATEDIFF(DAY, DATEADD(DAY, - 1,
CURRENT_TIMESTAMP), dtReading) = 0)
You have split the time from the date so you have to check one time interval for yesterday and another for today.
If you are on SQL Server 2008 and have stored only the date part in dtReading you could use something like this.
select count(R.CardID) as CardCount
from ReaderData as R
where controllerID = 28 and
(
(
R.dtReading = cast(dateadd(day, -1, getdate()) as date) and
R.ReaderTime >= '20:00:00'
) or
(
R.dtReading = cast(getdate() as date) and
R.ReaderTime < '08:00:00'
)
)
Update
With the time values in dtReading it is easier.
Remove the time part from getdate() by casting to date then add the number of hours you want to create the datetime values you want to compare against.
select count(R.CardID) as CardCount
from ReaderData as R
where controllerID = 28 and
R.dtReading >= dateadd(hour, 20, dateadd(day, -1, cast(cast(getdate() as date) as datetime))) and
R.dtReading < dateadd(hour, 8, cast(cast(getdate() as date) as datetime))
I using MS SQL Sever and I want to filter my query by only "today" registers, example
select * from tbl where [FieldDate] >= "Today Date"
I know I can use something like:
[FieldDate] >= DATEADD(DAY, 0, DATEDIFF(DAY, 0, CURRENT_TIMESTAMP))
or
[FieldDate] >= CAST(FLOOR( CAST( GETDATE() AS FLOAT))AS DATETIME)
But, what is the best way to do that?, thanks a lot.
Note: I can't use the "convert(date, getdate())".
This should work:
SELECT *
FROM tbl
WHERE [FieldDate] >= CONVERT(DATE,GETDATE())
AND [FieldDate] < CONVERT(DATE,DATEADD(DAY,1,GETDATE()))
For SQL Server 2005:
SELECT *
FROM tbl
WHERE [FieldDate] >= CONVERT(VARCHAR(8),GETDATE(),112)
AND [FieldDate] < CONVERT(VARCHAR(8),DATEADD(DAY,1,GETDATE()),112)
Try
SELECT *
FROM tbl
WHERE DATEDIFF(DD, [FieldDate], getdate()) = 0
I am looking for a good SQL Statement to select all rows from the previous day from one table. The table holds one datetime column. I am using SQL Server 2005.
get today no time:
SELECT dateadd(day,datediff(day,0,GETDATE()),0)
get yestersday no time:
SELECT dateadd(day,datediff(day,1,GETDATE()),0)
query for all of rows from only yesterday:
select
*
from yourTable
WHERE YourDate >= dateadd(day,datediff(day,1,GETDATE()),0)
AND YourDate < dateadd(day,datediff(day,0,GETDATE()),0)
To get the "today" value in SQL:
convert(date, GETDATE())
To get "yesterday":
DATEADD(day, -1, convert(date, GETDATE()))
To get "today minus X days": change the -1 into -X.
So for all yesterday's rows, you get:
select * from tablename
where date >= DATEADD(day, -1, convert(date, GETDATE()))
and date < convert(date, GETDATE())
It's seems the obvious answer was missing. To get all data from a table (Ttable) where the column (DatetimeColumn) is a datetime with a timestamp the following query can be used:
SELECT * FROM Ttable
WHERE DATEDIFF(day,Ttable.DatetimeColumn ,GETDATE()) = 1 -- yesterday
This can easily be changed to today, last month, last year, etc.
SELECT * from table_name where date_field = DATE_SUB(CURRENT_DATE(),INTERVAL 1 DAY);
Its a really old thread, but here is my take on it.
Rather than 2 different clauses, one greater than and less than. I use this below syntax for selecting records from A date. If you want a date range then previous answers are the way to go.
SELECT * FROM TABLE_NAME WHERE
DATEDIFF(DAY, DATEADD(DAY, X , CURRENT_TIMESTAMP), <column_name>) = 0
In the above case X will be -1 for yesterday's records
This should do it:
WHERE `date` = CURDATE() - INTERVAL 1 DAY
Can't test it right now, but:
select * from tablename where date >= dateadd(day, datediff(day, 1, getdate()), 0) and date < dateadd(day, datediff(day, 0, getdate()), 0)
In SQL Server do like this:
where cast(columnName as date) = cast(getdate() -1 as date)
You should cast both sides of the expression to date to avoid issues with time formatting.
If you need to control interval in more detail, then you should try something like:
declare #start datetime = cast(getdate() - 1 as date)
declare #end datetime = cast(getdate() - 1 as date)
set #end = dateadd(second, 86399, #end)
Another way to tell it "Yesterday"...
Select * from TABLE
where Day(DateField) = (Day(GetDate())-1)
and Month(DateField) = (Month(GetDate()))
and Year(DateField) = (Year(getdate()))
This conceivably won't work well on January 1, as well as the first day of every month. But on the fly it's effective.
Well, its easier to cast the datetime column to date and than compare.
SELECT * FROM TABLE_NAME WHERE cast(COLUMN_NAME as date) =
dateadd(day,0, convert(date, getdate(), 105))
A simple alternative
Select GETDATE() - 1
Change 1 to go back that many number of days
PS : This gives you timestamp accuracy.
This worked a charm:
SELECT * FROM mytable WHERE date(mydate) = DATE_SUB(CURDATE(), INTERVAL 1 DAY);
subdate(now(),1) will return yesterdays timestamp
The below code will select all rows with yesterday's timestamp
Select * FROM `login` WHERE `dattime` <= subdate(now(),1) AND `dattime` > subdate(now(),2)