Consider a table with multiple rows with dates:
Date
------
5/9/2022
5/27/2022
4/18/2022
6/2/2022
7/1/2022
6/6/2022
7/8/2022
7/6/2022
7/22/2022
7/19/2022
7/11/2022
current query is returning all rows DATE <= GETDATE()+1
so it would be returning all dates <=7/9/2022 when it actually needs to be <=7/11/22. This being this column never has a date that falls on a weekend or holiday. So on days like Fridays, the query should be trying to pull all rows <= to that coming Monday (the next date in the column or work day). This query has multiple where conditions as well.
WHERE (_Header.CODE IN ('10', '15')) AND (_Header.LOCATION = '89') AND (_Header.OR_NO > '0') AND (_Header.DATE <= GETDATE()+1)
This would give you the next day in a date field after today. It is a simple common table expression you could use in your query. You would just request all dates be <= to the date that is retrieved from the cte.
with cte(nextDay)
AS (SELECT TOP 1 cal_date FROM calendar
WHERE cal_date > GETDATE()
ORDER BY cal_date)
SELECT * FROM cte
I have a google bigquery table with orders with a DATE column and other columns related to the orders. The starting date of the dataset is from 2021-01-01 (yyyy-mm-dd).
My aim is to filter on the DATE column from last year and this year to the previous iso week. For this, I used the ISOWEEK to create a new column:
WITH
last_week_last_year AS (
SELECT
DATE,
EXTRACT(ISOWEEK FROM DATE) AS isoweek,
FROM
`orders`
WHERE
EXTRACT(ISOWEEK FROM DATE) = EXTRACT(ISOWEEK FROM CURRENT_DATE())-1
GROUP BY 1, 2
ORDER BY DATE
)
SELECT * FROM last_week_last_year
This query results as the following table:
The issue is that when I filter on the original orders table by the DATE from the last_week_last_year table I get all the orders back instead of just the filtered version.
My method to filter is WHERE DATE IN (SELECT DATE FROM last_week_last_year) as seen below.
SELECT
*
FROM
`orders`
WHERE
DATE IN (SELECT DATE FROM last_week_last_year)
ORDER BY DATE DESC;
A snapshot of resulting table. It contains all of the records from 2021-01-01 until the latest day.
How can I make sure that on the latter query the table is filtered based on the first query's dates in DATE column?
I have a table with 2 date fields - OperativeTo and OperativeFrom. I have to check for the records for which OperativeTo is missing, then update OperativeTo as follows
OperativeTo = OperativeFrom [Year+1] - 1 day
That is, the operative date is equal to the OperativeFrom date of the same record in the following year minus 1 day. e.g. if a record has OperativeFrom date as 1/07/2015 then
OperativeTo will be 30/06/2016.
Try this:
BEGIN TRAN
SELECT * FROM YourTable
UPDATE YourTable
SET OperativeTo = DATEADD( DAY, -1, DATEADD( YEAR, 1, OperativeFrom))
WHERE OperativeTo IS NULL
SELECT * FROM YourTable
ROLLBACK
If it gives you desired result, get rid of BEGIN TRAN/ROLLBACK and run the query again. Also read about DATEADD() function.
I have an Audit table for each and every day. All add/modify/delete records are stored. When any record is deleted it doesn’t show up the next day. Something like below.
Date records
---- --------
15th 100
16th 102 - Pickup all records, between 15 and 16, which are not in 16th
17th 110 - Pickup all records, between 16 and 17, which are not in 17th
18th 150 - Pickup all records, between 17 and 18, which are not in 18th
.. So on..
This is an Audit table which has the deleted records in the previous day, but not present today. I need to pick up all the deleted records, between dates.
But I don’t want to hard code the dates, instead, it should work from date to today()
How to achieve this in a single SQL query? I tried using “Union” it works, but with hardcoded dates. Is there any way we can achieve as a generic query which works as of today.
You can use two levels of aggregation. The first gets the maximum date for each id. The second records on the delete on the next day:
select max_date + interval 1 day, count(*)
from (select a.id, max(date) as max_date
from audit a
group by a.id
) t
group by max_date
order by max_date;
You might want a where clause to limit the maximum date to before the maximum date in the data (otherwise everything will look like it is being deleted on the following day).
An alternative method uses lead():
select date + 1, count(*)
from (select a.*,
lead(date) over (partition by id order by date) as next_date
from audit a
) t
where next_date <> date_add(date, INTERVAL 1 DAY) or next_date is null
group by date
order by date;
If records can be resurrected and you still want to count them as deleted when they disappear, this is the better method.
Here is a db<>fiddle.
I have a table that contains multiple records for each day of the month, over a number of years. Can someone help me out in writing a query that will only return the last day of each month.
SQL Server (other DBMS will work the same or very similarly):
SELECT
*
FROM
YourTable
WHERE
DateField IN (
SELECT MAX(DateField)
FROM YourTable
GROUP BY MONTH(DateField), YEAR(DateField)
)
An index on DateField is helpful here.
PS: If your DateField contains time values, the above will give you the very last record of every month, not the last day's worth of records. In this case use a method to reduce a datetime to its date value before doing the comparison, for example this one.
The easiest way I could find to identify if a date field in the table is the end of the month, is simply adding one day and checking if that day is 1.
where DAY(DATEADD(day, 1, AsOfDate)) = 1
If you use that as your condition (assuming AsOfDate is the date field you are looking for), then it will only returns records where AsOfDate is the last day of the month.
Use the EOMONTH() function if it's available to you (E.g. SQL Server). It returns the last date in a month given a date.
select distinct
Date
from DateTable
Where Date = EOMONTH(Date)
Or, you can use some date math.
select distinct
Date
from DateTable
where Date = DATEADD(MONTH, DATEDIFF(MONTH, -1, Date)-1, -1)
In SQL Server, this is how I usually get to the last day of the month relative to an arbitrary point in time:
select dateadd(day,-day(dateadd(month,1,current_timestamp)) , dateadd(month,1,current_timestamp) )
In a nutshell:
From your reference point-in-time,
Add 1 month,
Then, from the resulting value, subtract its day-of-the-month in days.
Voila! You've the the last day of the month containing your reference point in time.
Getting the 1st day of the month is simpler:
select dateadd(day,-(day(current_timestamp)-1),current_timestamp)
From your reference point-in-time,
subtract (in days), 1 less than the current day-of-the-month component.
Stripping off/normalizing the extraneous time component is left as an exercise for the reader.
A simple way to get the last day of month is to get the first day of the next month and subtract 1.
This should work on Oracle DB
select distinct last_day(trunc(sysdate - rownum)) dt
from dual
connect by rownum < 430
order by 1
I did the following and it worked out great. I also wanted the Maximum Date for the Current Month. Here is what I my output is. Notice the last date for July which is 24th. I pulled it on 7/24/2017, hence the result
Year Month KPI_Date
2017 4 2017-04-28
2017 5 2017-05-31
2017 6 2017-06-30
2017 7 2017-07-24
SELECT B.Year ,
B.Month ,
MAX(DateField) KPI_Date
FROM Table A
INNER JOIN ( SELECT DISTINCT
YEAR(EOMONTH(DateField)) year ,
MONTH(EOMONTH(DateField)) month
FROM Table
) B ON YEAR(A.DateField) = B.year
AND MONTH(A.DateField) = B.Month
GROUP BY B.Year ,
B.Month
SELECT * FROM YourTableName WHERE anyfilter
AND "DATE" IN (SELECT MAX(NameofDATE_Column) FROM YourTableName WHERE
anyfilter GROUP BY
TO_CHAR(NameofDATE_Column,'MONTH'),TO_CHAR(NameofDATE_Column,'YYYY'));
Note: this answer does apply for Oracle DB
Here's how I just solved this. day_date is the date field, calendar is the table that holds the dates.
SELECT cast(datepart(year, day_date) AS VARCHAR)
+ '-'
+ cast(datepart(month, day_date) AS VARCHAR)
+ '-'
+ cast(max(DATEPART(day, day_date)) AS VARCHAR) 'DATE'
FROM calendar
GROUP BY datepart(year, day_date)
,datepart(month, day_date)
ORDER BY 1