SQL - Find value for the last 5 weeks and the next 5 weeks in the same query - sql

I need to find inventory values for the last 5 weeks and the next 5 weeks on any given day I run the query (going to connect to Excel and run daily).
I am able to find them individually but when done together I get no returns.
The following work individually, is there a way to combine and get all returns?
Select * FROM Table
WHERE vdvInventory.Count >= CAST(DATEADD(WEEK, -5, GETDATE()) as DATE)
alternatively
Select * FROM Table
WHERE DATEDIFF(WEEK,vdvInventory.Count,GETDATE() )<5
If I try adding both where statements into one with an ADD I get no returns.
For Example:
Select * FROM Table
WHERE DATEDIFF(WEEK,vdvInventory.Count,GETDATE() )<5
AND DATEDIFF(WEEK,vdvInventory.Count,GETDATE() )>5
Thanks for any help or guidance with this!

Your query doesn't work because you have a contradictory statement: same expression (DATEDIFF(WEEK,vdvInventory.Count,GETDATE())) cannot be less and greater than 5 at the same time.
Try instead the following:
Select * FROM Table
WHERE vdvInventory.Count >= CAST(DATEADD(WEEK, -5, GETDATE()) as DATE)
and vdvInventory.Count <= CAST(DATEADD(WEEK, 5, GETDATE()) as DATE)

Related

In Microsoft SQL Server, how to split rows using datetime data

As I am working on a project for my university, I am supposed to create a dashboard for machines downtime.
Every time that a machine is down during the day, the availability is calculated as [ 24 (hours) - Downtime / 24 (hours) ].
However, there are some situations where the machines are down more than 1 day, so it means that I have the split the number of hours that machine is down and distributed to the respective days.
Here is what the data looks like:
Here is what the result looks like:
My idea,
Create one temp table with number between specific range by SELECT DISTINCT SeqDateDiff = number FROM master..[spt_values] WHERE number BETWEEN 0 AND 1000.
PS: the range is 0 to 1000 in the sample, you can create wider range, but it should not be neccessary, you can consider remove the machine if already down over 1000 days. And there are some other methods to create this kind of range table, you can google it.
Then left join with your table with date difference by on target.DateDiff+1>seq.SeqDateDiff.
Then the rest is simple, just calculate out reported/completed based on different situations.
Check working sample at SQL fiddler.
Below is the codes:
select ServiceID,
case when SeqDateDiff>0 then cast(DATEADD(day, SeqDateDiff, Reported) As Date) else Reported end Started,
case when SeqDateDiff=DateDiff
then Completed
else DATEADD(second, -1, cast(cast(DATEADD(day, SeqDateDiff+1, Reported) As Date) as DateTime))
end Completed,
DateDiff, SeqDateDiff
from (select ServiceID, Completed, Reported, DATEDIFF(day, Reported, Completed) DateDiff from YourTable) target
left join (
SELECT DISTINCT SeqDateDiff = number FROM master..[spt_values] WHERE number BETWEEN 0 AND 1000
) seq on target.DateDiff+1>seq.SeqDateDiff
select case when datediff(hh, reported, completed)>12 then 12 else
datediff(hh, reported, completed) end from yourtable
if day(reported)<>day(completed)
begin
select datediff(hh, cast(completed as date), completed) from yourtable
end
Assuming it's never down more than 2 days. If so, adjust logic accordingly...

Querying result from select part of statement

I have a stored procedure to work out how many working days between two dates
select
casekey, LoginName, casestartdatedate,
dbo.CalcWorkDaysBetween(casestartdatedate, GETDATE()) AS 'WD'
from
Car_case with (nolock)
where
dbo.CalcWorkDaysBetween(casestartdatedate, GETDATE()) <= DATEADD(dd,DATEDIFF(dd, 0, GETDATE()), -60)
and CaseClosedDateDate is null
order by
CaseStartDateDate asc
In my select part of statement I want to show the number of working days between the case start date and today's date. This part is fine. But I only want to return cases where the 'working days' is 60 days or greater - I'm having trouble with this part of query. See my code above. not too sure why its not working. It's returning results less than and greater than 60 days making me realize I've gone wrong somewhere.
Any help would be appreciated!
If I understand correctly, you just need to fix the where condition:
select casekey, LoginName, casestartdatedate,
dbo.CalcWorkDaysBetween(casestartdatedate, GETDATE()) AS WD
from Car_case cc with (nolock)
where dbo.CalcWorkDaysBetween(casestartdatedate, GETDATE()) >= 60 and
CaseClosedDateDate is null
order by CaseStartDateDate asc;
Note: In your version you are comparing the result of the function (which is presumably an integer) to a date.

Joining multiple tables returning duplicates

I am trying the following select statement including columns from 4 tables. But the results return each row 4 times, im sure this is because i have multiple left joins but i have tried other joins and cannot get the desired result.
select table1.empid,table2.name,table2.datefrom, table2.UserDefNumber1, table3.UserDefNumber1, table4.UserDefChar6
from table1
inner join table2
on table2.empid=table1.empid
inner join table3
on table3.empid=table1.empid
inner join table4
on table4.empid=table1.empid
where MONTH(table2.datefrom) = Month (Getdate())
I need this to return the data without any duplicates so only 1 row for each entry.
I would also like the "where Month" clause at the end look at the previous month not the current month but struggling with that also.
I am a bit new to this so i hope it makes sense.
Thanks
If the duplicate rows are identical on each column you can use the DISTINCT keyword to eliminate those duplicates.
But I think you should reconsider your JOIN or WHERE clause, because there has to be a reason for those duplicates:
The WHERE clause hits several rows in table2 having the same month on a single empid
There are several rows with the same empid in one of the other tables
both of the above is true
You may want to rule those duplicate rows out by conditions in WHERE/JOIN instead of the DISTINCT keyword as there may be unexpected behaviour when some data is changing in a single row of the original resultset. Then you start having duplicate empids again.
You can check if a date is in the previous month by following clause:
date BETWEEN dateadd(mm, -1, datefromparts(year(getdate()), month(getdate()), 1))
AND datefromparts(year(getdate()), month(getdate()), 1)
This statment uses DATEFROMPARTS to create the beginning of the current month twice, subtract a month from the first one by using DATEADD (results in the beginning of the previous month) and checks if date is between those dates using BETWEEN.
If your query is returning duplicates, then one or more of the tables have duplicate empid values. This is a data problem. You can find them with queries like this:
select empid, count(*)
from table1
group by empid
having count(*) > 1;
You should really fix the data and query so it returns what you want. You can do a bandage solution with select distinct, but I would not usually recommend that. Something is causing the duplicates, and if you do not understand why, then the query may not be returning the results you expect.
As for your where clause. Given your logic, the proper way to express this would include the year:
where year(table2.datefrom) = year(getdate()) and
month(table2.datefrom) = month(Getdate())
Although there are other ways to express this logic that are more compatible with indexes, you can continue down this course with:
where year(table2.datefrom) * 12 + month(table2.datefrom) = year(getdate()) * 12 + Month(Getdate()) - 1
That is, convert the months to a number of months since time zero and then use month arithmetic.
If you care about indexes, then your current where clause would look like:
where table2.datefrom >= dateadd(day,
- (day(getdate) - 1),
cast(getdate() as date) and
table2.datefrom < dateadd(day,
- (dateadd(month, 1, getdate()) - 1),
cast(dateadd(month, 1, getdate()) as date)
Eliminate duplicates from your query by including the distinct keyword immediately after select
Comparing against a previous month is slightly more complicated. It depends what you mean:
If the report was run on the 23rd Jan 2015, would you want 01/12/2014-31/12/2014 or 23/12/2014-22/01/2015?

SQL to filter for records more than 30 days old

Suppose I have the following query:
select customer_name, origination_date
where origination_date < '01-DEC-2013';
I would like to select all customers that have an origination date older than 30 days. Is there a way in SQL (oracle, if specifics needed) to specify it in a more dynamic approach than manually entering the date so that I don't need to update the query every time I run it?
Thanks!
Sure try something like this:
select customer_name, origination_date where
origination_date >= DATEADD(day, -30, GETUTCDATE());
This basically says where the origination_date is greater or equal to 30 days from now. This works in Microsoft SQL, not sure but there is probably a similar function on Oracle.
in Oracle, when you subtract dates, by default you get the difference in days, e.g.
select * from my_table where (date_1 - date_2) > 30
should return the records whose date difference is greater than 30 days.
To make your query dynamic, you parameterize it, so instead of using hard coded date values, you use:
select * from my_table where (:date_1 - :date_2) > :threshold
If you are using oracle sql developer to run such a query, it will pop up a window for you to specify the values for your paramteres; the ones preceded with colon.

SQL 2005 fetching data for current year

I have a view that holds sales data from 2012 till date, I need to write the query that show me only current year sales (2013).
This is what I tried in the first stage
SELECT *
FROM [Sales_Data]
WHERE invoiceDate between '2013-01-01' and '2013-12-31'
this query takes 2 sec to load the data,I though to change the query to fetch data that not required me to update it manually and this is what I found on the Net:
select * from [Sales_Data]
where datepart(yyyy,invoiceDate) =datepart(yyyy,getdate())
and datepart(yyyy,invoiceDate) =datepart(yyyy,getdate())
As a result this query takes much longer to show the data (9 sec).
Please let me know if there is a better query to define and get data in less time ?
Your second query requires sql server to perform a calculation for each row you are querying against.
The following query more closely matches your original select statement.
select * from [Sales_data]
where invoiceDate between DATEADD(YEAR, DATEDIFF(YEAR, 0, GETDATE()), 0) --- First Day of current year
and DATEADD(MILLISECOND, -3,DATEADD(YEAR, DATEDIFF(YEAR, 0, GETDATE()) + 1, 0)) --- Last Day of current year
Depending on what is going on with the view you are querying against, you may also benefit from having an index which includes the invoiceDate field.
You may want to check the execution plan generated when you run your query to see what is going on behind the scenes when the query runs.