SQL get records in the same week - sql

I have a table that contains records with a column indicates the Date. Given a record, I would like to select all records that are in the same week as the record. How can SQL do that?
I should say that I'm using SQLite.

You can use DATEPART with wk to get the current week. Then just check for equality.
In this case, I have also checked yy to make sure that you do not check the year of a previous week.
SELECT *
FROM TABLE
WHERE DATEPART(wk, TABLE.DATECOLUMN)
= DATEPART(wk, (SELECT DATECOLUMN FROM TABLE WHERE ID = GivenID))
AND DATEPART(yy, TABLE.DATECOLUMN) = DATEPART(yy, (SELECT DATECOLUMN FROM TABLE WHERE ID = GivenID))
UPDATE FOR SQLITE
To do this in SQLLite, Refer to this SO question and then this article that states %W is what you use to get week and %Y for year. Which gives you:
SELECT *
FROM TABLE
WHERE STRFTIME('%W', TABLE.DATECOLUMN)
= STRFTIME('%W', (SELECT DATECOLUMN FROM TABLE WHERE ID = GivenID))
AND STRFTIME('%Y', TABLE.DATECOLUMN)
= STRFTIME('%Y', (SELECT DATECOLUMN FROM TABLE WHERE ID = GivenID))

Use the datediff() function:
datediff(ww,start_date,end_date) < 1

You can use BETWEEN to specify the records you want.
SELECT * FROM records WHERE datecolumn between 'YYYY/MM/DD' AND 'YYYY/MM/DD'

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)
)

Select "YYYY" component only from DateTime column

Using SQLCe, I have a column of DateTime type. I would like to filter just by year. Is it possible or should I store year separately, which seems to me redundant?
E.g. get distinct results of 2010,2011,2013.
Thanks
think you have the DATEPART function (but not the YEAR function)
so
select DatePart(yyyy, <yourDateTime>)
or if that's for ordering, of course
order by DatePart(yyyy, <yourDatetime>)
EDIT
select max(InvoiceID)
from yourTable
where DatePart(yyyy, IssuedDate) = 2013
You can use the DATEPART function to return the year for that column:
SELECT DATEPART(yyyy, datetimecolumn) FROM YourTable
You can then filter with a where clause:
WHERE datetimecolumn = 2014
The usual way to do this is to use a range filter:
select *
from table
where datecolumn >= '2012/01/01' and datecolumn < '2013/01/01'
This has the benefit that any index you may have on datecolumn can be used.
Since the answer you accepted shows that you only care about one single year, your objection to this answer doesn't really apply.
select max(InvoiceID)
from table
where IssuedDate >= '2012/01/01' and IssuedDate < '2013/01/01'
will work just fine.

Add one for every row that fulfills where criteria between period

I have a Postgres table that I'm trying to analyze based on some date columns.
I'm basically trying to count the number of rows in my table that fulfill this requirement, and then group them by month and year. Instead of my query looking like this:
SELECT * FROM $TABLE WHERE date1::date <= '2012-05-31'
and date2::date > '2012-05-31';
it should be able to display this for the months available in my data so that I don't have to change the months manually every time I add new data, and so I can get everything with one query.
In the case above I'd like it to group the sum of rows which fit the criteria into the year 2012 and month 05. Similarly, if my WHERE clause looked like this:
date1::date <= '2012-06-31' and date2::date > '2012-06-31'
I'd like it to group this sum into the year 2012 and month 06.
This isn't entirely clear to me:
I'd like it to group the sum of rows
I'll interpret it this way: you want to list all rows "per month" matching the criteria:
WITH x AS (
SELECT date_trunc('month', min(date1)) AS start
,date_trunc('month', max(date2)) + interval '1 month' AS stop
FROM tbl
)
SELECT to_char(y.mon, 'YYYY-MM') AS mon, t.*
FROM (
SELECT generate_series(x.start, x.stop, '1 month') AS mon
FROM x
) y
LEFT JOIN tbl t ON t.date1::date <= y.mon
AND t.date2::date > y.mon -- why the explicit cast to date?
ORDER BY y.mon, t.date1, t.date2;
Assuming date2 >= date1.
Compute lower and upper border of time period and truncate to month (adding 1 to upper border to include the last row, too.
Use generate_series() to create the set of months in question
LEFT JOIN rows from your table with the declared criteria and sort by month.
You could also GROUP BY at this stage to calculate aggregates ..
Here is the reasoning. First, create a list of all possible dates. Then get the cumulative number of date1 up to a given date. Then get the cumulative number of date2 after the date and subtract the results. The following query does this using correlated subqueries (not my favorite construct, but handy in this case):
select thedate,
(select count(*) from t where date1::date <= d.thedate) -
(select count(*) from t where date2::date > d.thedate)
from (select distinct thedate
from ((select date1::date as thedate from t) union all
(select date2::date as thedate from t)
) d
) d
This is assuming that date2 occurs after date1. My model is start and stop dates of customers. If this isn't the case, the query might not work.
It sounds like you could benefit from the DATEPART T-SQL method. If I understand you correctly, you could do something like this:
SELECT DATEPART(year, date1) Year, DATEPART(month, date1) Month, SUM(value_col)
FROM $Table
-- WHERE CLAUSE ?
GROUP BY DATEPART(year, date1),
DATEPART(month, date1)

Return just the last day of each month with SQL

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