I have sql query which returns record by date specified
What I want to do is group them by 1 hour interval
My query returns a date and interval.
interval value looks like this
8:00,8:30,9:00,9:30,10:00
as you can see the interval has produce 5 value what I want to do is group them by this
8:00-9:00,9:00-10:00
I have designed a query:
SELECT DATEPART(HOUR,VC.DATE+ VC.INTERVAL) AS DATE
,DATEPART(HOUR,VC.INTERVAL) AS INTERVAL
FROM VMUK_Q1R_IB_CONSOLIDATED VC
But the problem with this it display like this 8,8,9,9,10
How to I achieve this?
What you need is to create a set of hourly values and join back to it based on the hour part of your value. This will make sure the missing 'buckets' are represented. The following CTE will give you the lookup for 24 hours - you could do the same thing with a static lookup table too.
with ranges
as
(
select 0 as value
union all
select r.value+ 1 from ranges r where r.value <= 24
)
select
r.value start
from ranges r
You could fix this by a calculation or formatting. I think formatting would be simpler for this example. Try this:
SELECT Convert(VarChar(20), DATEPART(HOUR,VC.INTERVAL)) + ':00' AS DATE
,DATEPART(HOUR,VC.INTERVAL) AS INTERVAL
FROM VMUK_Q1R_IB_CONSOLIDATED VC
If you want the full date + time shown, rounded down, try this:
SELECT Convert(VarChar(20), VC.Date, 101) + Convert(VarChar(20), DATEPART(HOUR,VC.INTERVAL)) + ':00' AS DATE
,DATEPART(HOUR,VC.INTERVAL) AS INTERVAL
FROM VMUK_Q1R_IB_CONSOLIDATED VC
If you want time ranges too, try this:
SELECT Convert(VarChar(20), VC.Date, 101) + Convert(VarChar(20), DATEPART(HOUR,VC.INTERVAL)) + ':00' AS DATE,
,DatePart(HOUR,VC.INTERVAL)) + ':00 - ' + DatePart(HOUR, DateAdd(HOUR, VC.INTERVAL, 1)) + ':00' AS TimeRange
,DATEPART(HOUR,VC.INTERVAL) AS INTERVAL
FROM VMUK_Q1R_IB_CONSOLIDATED VC
SELECT
DATEPART(HOUR,VC.DATE+ VC.INTERVAL) AS DATE,
case DATEPART(HOUR,VC.INTERVAL)
when 0 then '00:00-00:59'
when 1 then '01:00-01:59'
.
.
etc.
.
.
when 22 then '22:00-22:59'
when 23 then '23:00-23:59'
end AS INTERVAL
FROM VMUK_Q1R_IB_CONSOLIDATED VC
Related
I'm looking for a way to have my sql query change the dates in my query on the 15th of every month so my data pulls have a "rolling 12 months". For example, right now, my query pulls the dates (YYYYQMM) between 2018411 and 2019410. I have it hard coded so it looks like this:
Select *
From Table
WHERE Spend_Period_YYYYQMM >= 2018411 and Spend_Period_YYYYQMM <= 2019410
I would like to have a solution that on Dec 15th it changes the dates to 2018412 and 2019411.
I have a solution to change the dates every month like below but would like the dates to change on the 15th:
Spend_Period_YYYYQMM between to_char(date(current_date - cast('13 month' as interval)),'YYYYQMM')
and to_char(date(current_date - cast('2 month' as interval)),'YYYYQMM')
How should I got about it
We can use some CASE clauses and the EOMONTH function along with GetDate() to get your desired range.
DECLARE #date DATETIME = GETDATE();
select case
when day(#date) <= 14
then EOMONTH(#date, -13)
when day(#date) >= 15
then EOMONTH(#date, -12)
end as RollingYearBegin
,case
when day(#date) <= 14
then EOMONTH(#date, -2)
when day(#date) >= 15
then EOMONTH(#date, -1)
end as RollingYearEnd
into #RollingYear
Then if you need the values formatted in that specific way when you call them, you could either complicate that temp table above a bit more, or just make another little table
Select cast(concat(datepart(yyyy,RollingYearBegin), datepart(q,RollingYearBegin), datepart(MM,RollingYearBegin)) as bigint) as YearBegin
,cast(concat(datepart(yyyy,RollingYearEnd), datepart(q,RollingYearEnd), datepart(MM,RollingYearEnd)) as bigint) as YearEnd
into #YYYYQMM
From #RollingYear
Then, in your query, it would be:
Select *
From Table
WHERE Spend_Period_YYYYQMM BETWEEN (Select YearBegin from #YYYYQMM) AND (Select YearEnd from #YYYYQMM)
I'm trying to SELECT all the rows from a SQL database which are between an hour interval, for every day.
The datetime column is called "Dt" and has the following datetime format: 2019-10-17 16:03:43
I'd like to extract all the rows from this table where the Dt was between 22:00:00 and 02:00:00, for everyday.
SELECT *
FROM MY_TABLE
WHERE "Dt" BETWEEN '*-*- 22:00:00' AND '*-*- 02:00:00';
where * should be any...
Thanks for your support!
EDIT: I forgot to mention: I'm using the integrated SQL interpreter from DB Browser for SQLite
You need to extract the time part of the date and compare that it is within the range. Since midnight is between 22 and 2, you will need to split it to two comparisons, time between 22 and 0 and between 0 and 2.
To see how to extract the time take a look at this question.
With Postgres, assuming dt is defined as timestamp you can do the following:
SELECT *
FROM MY_TABLE
WHERE "Dt" BETWEEN "Dt"::date + time '22:00:00' and ("Dt"::date + 1) + time '02:00:00'
Or if you want to exclude timestamps at precisely 02:00:00
SELECT *
FROM MY_TABLE
WHERE "Dt" >= "Dt"::date + time '22:00:00'
and "Dt" < ("Dt"::date + 1) + time '02:00:00'
select DT_time from (
select cast (substr(to_char(Dt,'dd-mm-yyyy HH:MM:SS'),12,2) as integer ) as DT_time from MY_TABLE )
where DT_time between 2 and 22;
between 22:00:00 and 02:00:00
means:
SELECT *
FROM MY_TABLE
WHERE
substr(Dt, 12) BETWEEN '22:00:00' AND '23:59:59'
OR
substr(Dt, 12) BETWEEN '00:00:00' AND '02:00:00'
This will work ::
SELECT *
FROM MY_TABLE
WHERE DATEPART(HOUR, Dt)>22
AND DATEPART(HOUR, Dt)<2
Update :
SELECT *
FROM MY_TABLE
WHERE Dt Between DATEADD (hour,22,DATEADD(day, DATEDIFF(day, 0, Dt), 0)) AND DATEADD (hour,2,DATEADD(day, DATEDIFF(day, -1, Dt), 0))
SELECT *
FROM MY_TABLE
WHERE DATEPART(HOUR, Dt)>22
OR DATEPART(HOUR, Dt)<2
Above query work for you..
1st one will check only for particular date and consecutive next date along with your time range.
But If you don't care about dates and only looking for time interval in particular hours then 2nd one is for you.
For SQLite :
SELECT *
FROM MY_TABLE
WHERE strftime('%H','Dt')>22
OR strftime('%H','Dt')<2
Oracle SQL:
I been trying to get this some snippet of query working. When you run it, it prompts you for an hour, and displays no records. I don’t want the query to have a static hour as it will need to be run 4 times a day.
So from the ‘&date’ input, I want it to show data for the past 24 hours. Is that possible?
dt_time = timestamp(6) field
select distinct to_char(dt_ time,'dd/mm/yyyy hh24'), fault_description
from order
where to_char(dt_time,'hh24') <= '&date' -24
order by to_char(dt_ time,'dd/mm/yyyy hh24');
Example, if you enter 10 (when query executed) it will show the data from 10(:00) through to 10(:00)next day
[Hope there is enough info for someone to answer, please]
Use a combination of between and interval:
where dt_time between
to_date(&date, 'ddmmyyyy hh24') and
to_date(&date, 'ddmmyyyy hh24') + interval '24' hour
You'll need to pass/parse the input date as a full date and not only the hour part, in order to prevent unexpected results.
You can use NUMTODSINTERVAL in a CTE to get the hour as user input.
WITH t_hour( h ) AS
( SELECT NUMTODSINTERVAL(&d,'HOUR' ) h FROM DUAL
)
SELECT DISTINCT TO_CHAR(dt_time,'dd/mm/yyyy hh24'),
fault_description
FROM ORDER
CROSS JOIN t_hour
WHERE dt_time BETWEEN TRUNC(SYSDATE) + h AND TRUNC(SYSDATE) + 1 + h
ORDER BY 1;
You need to make use of SYSDATE as you are fetching last one day data.
Also if you add or subtract number with a date column the offset will be number of days, not number of hours. So you need to use &date/24
Try this:
select distinct to_char(dt_time,'dd/mm/yyyy hh24'), fault_description
from order
where dt_time - &date / 24 between TRUNC(sysdate-1) and TRUNC(sysdate)
order by to_char(dt_ time,'dd/mm/yyyy hh24');
Please comment.
WHERE DATEDIFF(SYSDATE,DT_TIME) * 24 < &DATE AND DT_TIME < SYSDATE
I have a max date in my query and If the max date is current month then I want always get previous month’s date. How can I do that?
For example, today is 20160825. If the max date is 20160801 then I want to get 20160701. But, if the max date is 20160501 then I just want to get without changes - 20160501.
SELECT
DEFN_DK,
MAX(SNAPSHOT_MTH)
FROM myTable
WHERE TOT_AMT >0
GROUP BY DEFN_DK
Since your SNAPSHOT_MTH column is an integer (why?) you can not use any of the otherwise very useful timestamp functions. So it's back to integer math, creating a "month" from your snapshot "date" through integer division by 100. This can be compared to CURRENT_DATE by converting that to a string and then casting it to an integer. Going back 1 month similarly requires some math. Not entirely efficient, but here goes:
SELECT DEFN_DK,
CASE max(SNAPSHOT_MTH) / 100
WHEN tochar(CURRENT_DATE, 'YYYYMM')::int THEN
((max(SNAPSHOT_MTH) / 100) - 1) * 100 + 1
-- or max(SNAPSHOT_MTH) - 100, if you know it always ends in 01
ELSE max(SNAPSHOT_MTH)
END AS SNAPSHOT_MTH
FROM myTable
WHERE TOT_AMT > 0
GROUP BY DEFN_DK;
select
defn_dk,
case max(snapshot_mth)
when date_trunc('month', current_date) then max(snapshot_mth) - interval '1 month'
else max(snapshot_mth)
end
from mytable
where tot_amt >0
group by defn_dk
show this, two examples:
select
case when date_trunc('month',dd) = date_trunc('month',now())
then dd - interval'1 month' else date_trunc('day',dd) end
from
(
select '2016-08-04'::date as dd
) d;
and
select
case when date_trunc('month',dd) = date_trunc('month',now())
then dd - interval'1 month' else date_trunc('day',dd) end
from
(
select '2016-05-04'::date as dd
) d;
I've a query having lot of datetime as result.
Suppose I want to count how much of these datetime are in a time slot like:
07:00 to 08:00
08:01 to 09:00
so I want something like this:
_______________________
| slot | count
|______________|________
| 7:00 - 8:00 | 10
| 8:01 - 9:00 | 2
I really don't know what i can do to have this result.
I've tried something like this but obv i get error:
SELECT something
FROM something
WHERE
CAST(DATEPART(hour, <data>) as varchar(2)) + ':' + CAST(DATEPART(minute, <data>)as varchar(2)) between <slot1> and <slot2>
TIPS: probably I'll get the time slots dynamically from the report services.
Here is query to accomplish what you seem to looking for:
SELECT CAST(DATEPART(HH, time) AS VARCHAR(2))+':00 - '+CAST(DATEPART(HH, time)+1 AS VARCHAR(2))+':00', COUNT(*)
FROM your_table
GROUP BY DATEPART(HH, time)
Here is code at SQL Fiddle
[EDIT]:
AS per the new requirement, below query can accomplish what you want:
SELECT (CAST(DATEPART(HH, time) AS VARCHAR(2)) +
CASE WHEN DATEPART(MI, time) <= 30 THEN ':00 - '+CAST(DATEPART(HH, time) AS VARCHAR(2))+':30'
ELSE ':30 - '+CAST(DATEPART(HH, time)+1 AS VARCHAR(2))+':00' END) AS r,
COUNT(*)
FROM your_table
GROUP BY
(CAST(DATEPART(HH, time) AS VARCHAR(2)) +
CASE WHEN DATEPART(MI, time) <= 30 THEN ':00 - '+CAST(DATEPART(HH, time) AS VARCHAR(2))+':30'
ELSE ':30 - '+CAST(DATEPART(HH, time)+1 AS VARCHAR(2))+':00' END)
Here is the code at SQL Fiddle
If you do not want to use CASE statement two times as in the above query then you can do a GROUP BY in an outer query enclosing the current as an inner query as below:
SELECT r, COUNT(*) AS cnt FROM
(
SELECT (CAST(DATEPART(HH, time) AS VARCHAR(2)) +
CASE WHEN DATEPART(MI, time) <= 30 THEN ':00 - '+CAST(DATEPART(HH, time) AS VARCHAR(2))+':30'
ELSE ':30 - '+CAST(DATEPART(HH, time)+1 AS VARCHAR(2))+':00' END) AS r
FROM your_table
) tab
GROUP BY r
Here is the code at SQL Fiddle
Let me know if it solved your problem.