How do i write a sql query that is contingent on 2 columns in one conditional? - sql

Take the following psuedo query on a table called userscore:
select average of userscore.points
where (userid = userid)
and ((userscore.year != given year) && (userscore.week != given week))
How do i write a query that will filter out a specific week/year column combination? For example this week is the 29th week of 2020. How do i write a query that will filter out only the 29th week of 2020 and not the 29th weeks of 2019/2018/2017 etc?

How do i write a query that will filter out only the 29th week of 2020 and not the 29th weeks of 2019/2018/2017 etc?
This is more of a question about boolean logic than SQL.
Assuming that given_year and given_week are the parameters to your query, you want something like:
where not (year = given_year and week = given_week)
You can also express this with or:
where year <> given_year or week <> given_week

Related

Compare 2 weeks data from this year to 2 weeks data last year

Imagine a simple parameterized query:
SELECT * FROM table
WHERE date BETWEEN #DS_START_DATE and #DS_END_DATE
This is useful for seeing data from today, yesterday, one week data and one year data. Now I am required to compare 2 weeks data of this week compared to last year. For example, today is the 30th of August. I have to compare 16-29 Aug 2021 data to 16-29 Aug 2020 data. Can anyone help with this?
You can return the results using or:
SELECT t.*
FROM table t
WHERE t.date BETWEEN #DS_START_DATE and #DS_END_DATE OR
t.date BETWEEN DATE_ADD(#DS_START_DATE, INTERVAL -1 YEAR) AND DATE_ADD(#DS_END_DATE, INTERVAL -1 YEAR);
One caution is that the comparison periods might be off if they include leap days. Your question doesn't specify how to handle that.

What method can I use to get a different date value for a stored field in my database?

I am working on a project that is asking me to return different date values based on the scenario and I am not quite sure how to write this out. I think that I'm just not understanding how to apply the logic:
PAYFREQ is A then TRANS_DATE is 1st of the Year of COMPEFFDT
PAYFREQ is M then TRANS_DATE is 1st of the Month of COMPEFFDT
PAYFREQ is B then 1st day of the biweekly period ending with COMPEFFDT
PAYFREQ <> A and the only non-zero FIC amount for a calendar year has COMPEFFDT of December 31, then TRANS DATE is 1st of the Year of COMPEFFDT
Can anyone give me at least a base starting point in how to formulate this statement?
Assuming this is in a query, try the SWITCH statement. I'm not sure what you mean by the "1st of year of COMPEFFDT" though.
SELECT SWITCH (
PAYFREQ = "A", "1st of year of COMPEFFDT",
PAYFREQ = "M", "1st of the Month of COMPEFFDT",
...
) AS Result
Also, you should look at the guide for submitted a new question.

SQL - check if an order date occurs after the second Saturday in July

I am querying against a table of 4 yrs of order transactions (pk = order number) and I'm looking to tag each record with particular date flags based on the order date - e.g., calendar year, calendar month, fiscal year, etc. There are date attributes that are specific to our business (e.g., not easily solved by a datepart function) that I'm having trouble with.
I was able to add "School Year" (for us that runs Aug 1 - July 31) using a case statement:
case
when datepart(month, oline.order_date_ready) between 8 and 12 then datepart(year, oline.order_date_ready)
else (datepart(year, oline.order_date_ready)-1)
end as school_yr
So for 1/19/2017, the above would return "2016", because to us the 2016 school year runs from Aug 1 2016 to July 31 2017.
But now I'm having trouble repeating the same kind of case statement for something called "Rollover Year". All of our order history tables are reset/"rolled over" on the 2nd Saturday in July every calendar year, so for example the most recent rollover date was Saturday July 9th 2016. Click to view - rollover year date ranges
My above case statement doesn't apply anymore because I can't just add "datepart(month, oline.order_date_ready) = 7" - I don't need the whole month of July, I just need all the orders occurring after the 2nd Saturday in that July. So in this example, I need everything occurring from Sat July 9 2016 to today to be flagged as rollover_date = 2016.
Is there a flexible way to do this without hard coding previous/future rollover dates into another table? That's the only way I can think to solve it currently, but I'm sure there must be a better way.
Thanks!
If you ask for the day-of-the-week of July 1st, then from there it's simple arithmetic, right? This query gives results matching your image:
SELECT y,
CONCAT(y, '-07-01')::timestamp +
CONCAT(6 - EXTRACT(DOW FROM CONCAT(y, '-07-01')::timestamp) + 7, ' days')::interval
FROM generate_series(2013, 2020) s(y)
ORDER BY y DESC
;
So given any date d from year y, if it comes before the 2nd Saturday of July, give it fiscal year y - 1. Otherwise give it fiscal year (school year?) y.

How to do a month search by sql query

I have 1 table in MS Access which is like:
id date
1 1/01/2016
2 1/01/2016
3 1/01/2016
How do I perform a search operation on it by month - meaning a search where the month is January/February?
Using dates as criteria in Access queries:
Contain a date within a specific month (regardless of year), such as December
DatePart("m", [SalesDate]) = 12
Returns items with a date in December of any year.
Where of course you replace [SalesDate] with your column...

Get month name with different month start and end dates

Getting the month for the current date is, obviously, straight forward, but I'm needing to get the month name with a different end date.
I need to get the month name with the start date of the month being the first Thursday after the first Wednesday of the month and the end date of the month being the first Wednesday of the following month. It's for an accounting thing, so I'm not going to argue with the spec!
e.g. for 2014, January would run from 9th Jan - 5th Feb, February would run from 6th February - 5th March, March would run from 6th March - 2nd April.
I would suggest that you create a table with your 'accounting months' in it, having a start date, end date and month name columns.
You could then query this to find the row where your date is between the start and end dates and return the month name. Putting this into a scalar function would then allow it to be reusable and relatively easily updated for next years months as well.
I think, as per Paddy's answer, a lookup table is the simplest thing to do. Here's one way to generate the rows for it:
; With Numbers(n) as (
select 4 union all select 5
), Months as (
select CONVERT(date,'20010104') as StartDt,CONVERT(date,'20010207') as EndDt,
DATENAME(month,'20010103') as Month
union all
select DATEADD(week,n1.n,StartDt),DATEADD(week,n2.n,EndDt),
DATENAME(month,DATEADD(week,n1.n,StartDt))
from Months,Numbers n1,Numbers n2 --Old-skool join, just for once
where DATEPART(day,DATEADD(week,n1.n,StartDt)) between 2 and 8 and
DATEPART(day,DATEADD(week,n2.n,EndDt)) between 1 and 7 and
StartDt < '21000101'
)
select * from Months option (maxrecursion 0)
(CW since this is effectively just an extension to Paddy's answer but I don't want to edit their answer, nor is it suitable for a comment