Date grouping in a simple sql query - sql

I need some help with a SQL query. I have a table in a SQL server database with three fields. Field1, Field2 and DateField. I want to do a count of how many records at any given time are returned where Field1 matches a set variable, Field2 matches a set variable, and the DateField is on the same day (24 hr day from 12:00am - 23:59pm)
select count(*)
from TableA
where Field1 = 'A'
and Field2 = 'B'
and DateField = TODAY
I need help with the date grouping. Any help would be appreciate.

In a nutshell:
and DateField >= TODAY and DateField < TOMORROW
specifically:
and DateField >= cast(current_timestamp as date) and DateField < cast(dateadd(dd, 1, current_timestamp) as date)
You can also use BETWEEN, but I prefer the exclusive upper bound. If find that approach less prone to mistakes, such as using 11:59pm as the end time and leaving records from 23:59.001 to 23:59.997 without a home, or matching on records that actually fall on midnight tomorrow.

Is this what you want?
select count(*)
from TableA
where Field1 = 'A' and Field2 = 'B' and
DateField = cast(getdate() as date);

Related

Extracting data from only the year

I have data in a table in SQL with dates, but how do I select only those that happen in 2021. (The dates look like 31-oct-2020) in the table. The dates are the actual date variable, not just text.
You should avoid storing your dates as text, but rather should use a proper date column. That being said, you may check the right 4 characters of the date string:
SELECT *
FROM yourTable
WHERE RIGHT(date_col, 4) = '2021';
If the column be an actual date type then use:
SELECT *
FROM yourTable
WHERE date_col >= '2021-01-01' AND date_col < '2022-01-01';
I suspect that your DB is Oracle after checking out your previous post. Then you can use
SELECT *
FROM yourTable
WHERE EXTRACT(year FROM dt) = 2021
or
SELECT *
FROM yourTable
WHERE TRUNC(dt,'YYYY') = date'2021-01-01'
or
SELECT *
FROM yourTable
WHERE dt BETWEEN date'2021-01-01' AND date'2021-12-31'
You can benefit the index if there's one on the date column(namely dt) by using the last SELECT statement
If using MSSQL, you can leverage the YEAR(...) to extract the year from a date.
Replace and , with the table name and date column name respectively.
select * from <tablename> where year(<datecolumn>) = 2021

SQL if statement for date range

Hi I was needing help with the syntax to add a condition where the current date is retrieved if today is after the 5th of each month but if its between the 1st to the 5th then it should retrieve the month before this month. Is it something you can help with please? Below is how my query is structured.
Select *
FROM table1
left join table2
on e.ENTITY_NBR = d.entity_nbr
and cast(getdate() as date) between MONTH_BEGIN_DATE and MONTH_END_DATE
Select *,
CASE WHEN day(GETDATE()) > 5 THEN GETDATE()
ELSE DATEADD(month,-1,getdate()) END as date
FROM table1
left join table2
on e.ENTITY_NBR = d.entity_nbr
and cast(getdate() as date) between MONTH_BEGIN_DATE and MONTH_END_DATE
Based on a vague description of your problem this is the best I can write.
If you simply want to include todays date (or the same date from last month if it's currently the 5th or earlier in the current month), then this can be done in your SELECT clause:
select
case
when datepart(day,getdate()) <= 5
then dateadd(month,-1,getdate())
else getdate()
end
If you want to actually use this date to compare to some field in your dataset, then you can include this same case expression in your WHERE clause.
where the current date is retrieved if today is after the 5th of each month but if its between the 1st to the 5th then it should retrieve the month before this month.
Based on this description, you want something like this:
select *
from table1 e left join
table2 d
on e.ENTITY_NBR = d.entity_nbr and
(day(getdate() > 5 and datediff(month, d.date_col, getdate()) = 0 or
day(getdate() <= 5 and datediff(month, d.date_col, getdate()) = 1)
)

Pending Monthly SQL Counts

The below query returns accurate info, I just haven't had any luck trying to make this:
1) More dynamic so I'm not repeating the same line of code every month
2) Formatted differently, so just 2 columns of month + year are needed to view pending counts by field1 + field2
Example code (basically, sum when (OPEN date is before/on the last day of the month) and (CLOSE date comes after the month OR it's still opened)
SELECT
SUM(CAST(case when OPENDATE <= '2014-11-30 23:59:59'
and ((CLOSED >= '2014-12-01')
or (CLOSED is null)) then '1' else '0' end as int)) Nov14
,SUM(CAST(case when OPENDATE <= '2014-12-31 23:59:59'
and ((CLOSED >= '2015-01-01')
or (CLOSED is null)) then '1' else '0' end as int)) Dec14
,SUM(CAST(case when OPENDATE <= '2015-01-30 23:59:59'
and ((CLOSED >= '2015-02-01')
or (CLOSED is null)) then '1' else '0' end as int)) Jan15
,FIELD1,FIELD2
FROM T
GROUP BY FIELD1,FIELD2
Results:
FIELD1 FIELD2 NOV14 DEC14 JAN15
A A 2 5 7
A B 6 8 4
C A 5 6 5
…
Instead of:
COUNT FIELD1 FIELD2 MO YR
14 A A 12 2014
18 A B 12 2014
16 C A 1 2015
...
Is there a way to get this in one shot? Sorry if this is a repeat topic, I've looked at some boards and they've helped me get closing counts.. but using a range between two date fields, I haven't had any luck.
Thanks in advance
One way to do it is to use a table of numbers or calendar table.
In the code below the table Numbers has a column Number, which contains integer numbers starting from 1. There are many ways to generate such table.
You can do it on the fly, or have the actual table. I personally have such table in the database with 100,000 rows.
The first CROSS APPLY effectively creates a column CurrentMonth, so that I don't have to repeat the call to DATEADD many times later.
Second CROSS APPLY is your query that you want to run for each month. It can be as complicated as needed, it can return more than one row if needed.
-- Start and end dates should be the first day of the month
DECLARE #StartDate date = '20141201';
DECLARE #EndDate date = '20150201';
SELECT
CurrentMonth
,FIELD1
,FIELD2
,Counts
FROM
Numbers
CROSS APPLY
(
SELECT DATEADD(month, Numbers.Number-1, #StartDate) AS CurrentMonth
) AS CA_Month
CROSS APPLY
(
SELECT
FIELD1
,FIELD2
,COUNT(*) AS Counts
FROM T
WHERE
OPENDATE < CurrentMonth
AND (CLOSED >= CurrentMonth OR CLOSED IS NULL)
GROUP BY
FIELD1
,FIELD2
) AS CA
WHERE
Numbers.Number < DATEDIFF(month, #StartDate, #EndDate) + 1
;
If you provide a table with sample data and expected output, I could verify that the query produces correct results.
The solution is written in SQL Server 2008.
Like this:
SELECT
FIELD1,FIELD2,datepart(month, OPENDATE), datepart(year, OPENDATE), sum(1)
FROM T
GROUP BY FIELD1,FIELD2, datepart(month, OPENDATE), datepart(year, OPENDATE)
But this of course is just based on OPENDATE, if you need to have the same thing calculated into several months, that's going to be more difficult, and you'll probably need a calendar "table" that you'll have to cross apply with this data.

SQL query to get average values over a list of time ranges

I would like to get the average value of some columns for a list of time ranges. The time ranges are not fixed so it is not the average value for every year or month.
I don't want to do a query against the database for every range and I would like, if possible, to do this query only once.
So it would be cool if we could replace the following queries for 2 time ranges to only one query.
SELECT AVG(column1) FROM Table1 WHERE dateColumn > startRange1 && dateColumn < endRange1
SELECT AVG(column1) FROM Table1 WHERE dateColumn > startRange2 && dateColumn < endRange2
NOTE: The list of time ranges can varies between 1 to 12 specified ranges.
case based aggregation is one way to do this in single query.
SELECT AVG(case when dateColumn > startRange1 && dateColumn < endRange1 then column1 end) as range1Avg,
AVG(case when dateColumn > startRange2 && dateColumn < endRange2 then column1 end) as range2Avg
FROM Table1

SQLserver query rows in between specific date

how could i get row by filtering in between specific date...
in my table, i have thousand of rows about Ordered Food.
I want to check ordered food between June-01-2011 1:00:00PM to June-05-2011 6:00:00pm.
how could i suppose to write t-sql code...
select *
from MyTable
where MyDate >= `2011-06-01T13:00:00` and MyDate < '2011-06-05T18:00:00'
if you want to include both datetimes:
select *
from MyTable
where MyDate between `2011-06-01T13:00:00` and '2011-06-05T18:00:00'
Making some wild assumption about your table structure basically do this...
Select * from ordered_food
where ordered_date
between '2011-06-01 13:00:00' and '2011-06-05 18:00:00'