SQL: How to find all results older than 1 year - sql-server

I have this query:
SELECT * FROM table1 WHERE YEAR(datecolumn) = YEAR(DATEADD(YEAR,-1,GETDATE()))
From my understanding, this query will show everything in that table that is older than 1 year. I'm trying to get a list of items that were first stocked over a year ago. Is this the correct query to be running or could it be made easier?
I need the script to be able to run without a fixed date range. So say I run it today and it gives me 100 rows, if I run it tomorrow, because the script is looking at the date I run it, it might return a different result set.

That query gives results for records of only the previous year.
To get records older than (today - 1 year) try this
SELECT *
FROM table1
WHERE datecolumn < DATEADD(YEAR,-1,CAST(GETDATE() AS DATE))
And to get records before the current year
SELECT *
FROM table1
WHERE datecolumn < DATEFROMPARTS(YEAR(GETDATE()),1,1)

This will give you everything from last "year"
SELECT *
FROM table1
WHERE YEAR(datecolumn) < YEAR(GETDATE())
But you want it to change day by date. In that case do this
SELECT *
FROM table1
WHERE datecolumn < DATEADD(YEAR,-1,GETDATE())

Related

Crystal Reports sales report showing all dates even when not existing

I have been searching for answers on this for a couple of days but not found any useful results.
A bit of the backstory:
I have about ~20k items that i'm trying to do a lifetime sales history report on.Some items have history from 1/1/2005. Sales are only noted on dates they occur.
Trying to graph first lifetime of sales history by days, first 6mo of sales, and last 30 days of sales. I don't have permission to add a temp table, so i am working with importing an excel file. (and for some reason you can't right-outer-join it to invoice date. im guessing because it's external?)
My problem is that there HAS to be a simple way to tell crystal to include/print missing dates without a lookup table. I've already got the start and end dates passed to parameters.
Isn't there a way to dynamically generate missing dates between {?PM-Start} to {?PM-End}? Using a lookup table to check if all days from 1/1/2005-currentdate match is 90,000,000,000 extra bloops to check.
That would take hours to run. It should be able to grab minumum(sale_date), and maximum(sale_date) and plop a record for each day whether it exists in the DB or not. (How is this not already a basic function?)
Or am I just missing something super simple?
Isn't there any way to dynamically generate missing dates between {?PM-Start} to {?PM-End}? Using a lookup table to check if all days from 1/1/2005-currentdate match is 90,000,000,000 extra bloops to check.
By using a query like below you can generate a calendar view to fill missing date:
;with years(yyyy) as (
select 2005
union all
select yyyy + 1
from years
where yyyy < datepart(year, getdate())
), months(mm) as (
select 1
union all
select mm + 1
from months
where mm < 12
), allDays(dd) as (
select 1
union all
select dd + 1
from allDays
where dd < 31
), calendar as (
select --datefromparts(y.yyyy, m.mm, d.dd) [date]
cast(cast(y.yyyy as varchar(4))+'-'+cast(m.mm as varchar(2))+'-'+cast(d.dd as varchar(2)) as date) [date]
from allDays d
cross join
months m
cross join
years y
where isdate(cast(y.yyyy as varchar(4))+ '/'+cast(m.mm as varchar(2))+'/'+cast(d.dd as varchar(2))) <> 0
)
select *
from calendar;
SQL Fiddle Demo

T-SQL find all records in a group with a max last modified date beyond a specific threshold

I have a Database table that has all the information I need arranged like so:
Inventory_ID | Dealer_ID | LastModifiedDate
Each Dealer_ID is attached to multiple Inventory_ID's. What I need is a query that calculates the Max Value LastModifiedDate for each dealer ID and then gives me a list of all the Dealer_ID's that have a last modified date beyond the last 30 days.
Getting The max last modified date for each Dealer_ID is simple, of course:
Select Dealer_ID, Max(LastModifiedDate)as MostRecentUpdate
from Inventory group by Dealer_ID order by MAX(LastModifiedDate)
The condition for records older than 30 day is also fairly simple:
LastModifiedDate < getdate() - 30
Somehow, I just can't figure out a way to combine the two that works properly.
Use HAVING:
Select Dealer_ID, Max(LastModifiedDate)as MostRecentUpdate
from Inventory
group by Dealer_ID
having LastModifiedDate < getdate() - 30
order by MAX(LastModifiedDate)
Check this query:
Select DT.DealerID, DT.MostRecentUpdate
(Select DealerID, Max(LastModifiedDate)as MostRecentUpdate
From YourTable
Group BY DealerID) DT
where DT.MostRecentUpdate < GETDATE() - 30

how to skip a day to previous in sql database if that day produce no files

i need to print the files From the current day plus from the day before...but if the day before is sunday then i want to print the files from saturday
i have a database containing a files of a month..each day produces some files but sunday is a holiday and at that day no files are generated.now i have done the query to pick the files in such a way that giving current date will results the files of that day and previous day. But the problem is on monday when i give the current date it produces files of monday and sunday... i dont want to print files of sunday as it is null,instead of that when am giving the current date if its is monday i should get the files of saturday instead of monday.
this is the code am using now
select files from table1 where [date]>=DATEADD(DAY,DATEDIFF(DAY,0,GETDATE()-1),0) ";
except for sundays i have entered the files for each day
insert into dbtable(date,files) values('date value',' filename');
Assuming your are using SQL Server (and not MySQL), you can use a CROSS APPLY to get data for the last two [dates] with files:
SELECT *
FROM dbo.table1 o
CROSS APPLY ( SELECT TOP 2 [date]
FROM dbo.table1 i
GROUP BY [date]
WHERE [date]>=DATEADD(DAY,DATEDIFF(DAY,0,GETDATE()-5),0)
ORDER BY [date] DESC
) det
WHERE det.[date] = o.[date]
Look for both dates, the current and the one before. From these records take the newer one.
select files
from table1
where date =
(
select max(date)
from table1
where date in (getdate(), getdate() - interval 1 day)
);
(Updated regarding Code-Monk's commment. Thanks.)
This is standard SQL except for the date manipulation which is MySQL specific. If you were mistaken with the DBMS tagged, then replace the part where a day is subtracted from current day with what's appropriate for your DBMS.)
UPDATE: You want to select from two days, the currect day and the last date before. As there should be no future records, this always means the two maximum dates in your table.
The slightly altered query using ORDER BY and LIMIT:
select files
from table1
where date in
(
select date
from table1
order by date desc limit 2
);
Try MySQL function DAYNAME(date1) to check for day is sunday,If so then get difference of two days instead of one.
mysql> SELECT DAYNAME(GETDATE());
+-----------------------+
| DAYNAME('2008-05-15') |
+-----------------------+
| Thursday |
+-----------------------+
1 row in set (0.01 sec)
If you are using SQL server,you can try datename function to get the day name:
datename(dw,getdate())
Try this for SQL Server:
SELECT files from table1
where [date]>=DATEADD(DAY,case when datename(dw,(GETDATE()-1))='SUNDAY' THEN -2 ELSE -1 END,getdate());
For MySQL Server Try:
SELECT files from table1
where `date`>=DATE_SUB(current_Date,interval (case when DAYNAME(date_sub(current_date,interval 1 day))='SUNDAY' THEN 2 ELSE 1 END) day);
Hope this works, because I don't have mysql here to test (only SQL Server):
SELECT files FROM table1
WHERE CAST([date] AS DATE) IN (CURDATE() - CASE DATEPART(dw,GETDATE()) WHEN 2 /* Monday */ THEN 2 ELSE 1 END, CURDATE())
The idea is to test if the date (as date only, no time part) falls in a specific list of dates, being today and yesterday or Saturday.

how to calculate all previous datas sum of a sql column on a date range report

I have a crystal report with debit credit columns using a sql command. This report contains a date to date filtering parameters. So the problem is if i filter the report to date range i need all the previous data sum using a sql command.
Select SUM(CAST(debit as DECIMAL(9,2)))- SUM(CAST(credit as DECIMAL(9,2)))
from sum_balance
where sum_date < sum_date
this is my code but i can't get the result from it. (e.g. : if the report starting from 2014-07-01 then i need the sum(debit - credit) of all previous data before 2014-07-01). Can anyone help me to find a solution for this. THe main thing is to add a brought forward balance using sql command on first row. If it is null then it should be 0.00.
Here is your sample table
CREATE TABLE #TEMP(DEBIT NUMERIC(20,2),CREDIT NUMERIC(20,2),DT VARCHAR(20))
INSERT INTO #TEMP
SELECT 1000 DEBIT,500 CREDIT,'2014-11-27' DT
UNION ALL
SELECT 2000 DEBIT,700 CREDIT,'2014-11-28' DT
UNION ALL
SELECT 3000 DEBIT,900 CREDIT,'2014-11-29' DT
I am updating answer for your updated requirement
QUERY 1
This will bring the total till current date, ie, for 2014-11-28 the amount will be (1000+2000)-(500+700), for 2014-11-29 the amount will be (1000+2000+3000)-(500+700+900)
SELECT T2.DEBIT,T2.CREDIT,T2.sum_date,
(SELECT SUM(DEBIT)-SUM(CREDIT) FROM sum_balance WHERE sum_date <= CAST(T2.sum_date AS DATE))
AMOUNT
FROM sum_balance T2
SQL FIDDLE
QUERY 2
This will bring the sum till previous day, that will be opening balance for today's date ie, for 2014-11-29 the amount will be (1000+2000)-(500+700). For easy understanding I have added the previous column also.
;WITH CTE AS
(
SELECT ROW_NUMBER() OVER(ORDER BY CAST(T2.sum_date AS DATE))RNO,
T2.DEBIT,T2.CREDIT,T2.sum_date,
ISNULL((SELECT SUM(DEBIT)-SUM(CREDIT) FROM sum_balance WHERE sum_date <= CAST(T2.sum_date AS DATE)),0)
AMOUNT
FROM sum_balance T2
)
SELECT C1.*,ISNULL(C2.AMOUNT,0) CARRYFORWARD
FROM CTE C1
LEFT JOIN CTE C2 ON C1.RNO=C2.RNO+1
SQL FIDDLE
You can use QUERY 2 and you will get opening balance till previous day in CARRYFORWARD column.
Please leave a message or comment for any changes.
When you need records previous than some date then you need to have that comparision date so that records can be extracted.
Your where clause where sum_date < sum_date won't work this way either you change the right side comparision operator in query or create a parameter in crystal so that user can enter the required end date during run time.
option 1:
E.g: where sum_date < currentdate
option 2:
Create a parameter and declare it in Record Selection Formula in crystal reports so that formed query will be something like
where sum_date < 2014-07-01
You can try this:-
SELECT SUM(CAST(debit as DECIMAL(9,2)))- SUM(CAST(credit as DECIMAL(9,2)))
FROM sum_balance
WHERE sum_date < (Select Max(sum_date) FROM sum_balance)

Query to create records between two dates

I have a table with the following fields (among others)
TagID
TagType
EventDate
EventType
EventType can be populated with "Passed Inspection", "Failed Inspection" or "Repaired" (there are actually many others, but simplifies to this for my issue)
Tags can go many months between a failed inspection and the ultimate repair... in this state they are deemed to be "awaiting repair". Tags are still inspected each month even after they have been identified as having failed. (and just to be clear, a “failed inspection” doesn’t mean the item being inspected doesn’t work at all… it still works, just not at 100% capacity…which is why we still do inspections on it).
I need to create a query that counts, by TagType, Month and Year the number of Tags that are awaiting repair. The end result table would look like this, for example
TagType EventMonth EventYear CountofTagID
xyz 1 2011 3
abc 1 2011 2
xyz 2 2011 2>>>>>>>>>>>>indicating a repair had been made since 1/2011
abc 2 2011 2
and so on
The "awaiting repair" status should be assessed on the last day of the month
This is totally baffling me...
One thought that I had was to develop a query that returned:
TagID,
TagType,
FailedInspectionDate, and
NextRepairDate,
then try and do something that stepped thru the months in between the two dates, but that seems wildly inefficient.
Any help would be much appreciated.
Update
A little more research, and a break from the problem to think about it differently gave me the following approach. I'm sure its not efficient or elegant, but it works. Comments to improve would be appreciated.
declare #counter int
declare #FirstRepair date
declare #CountMonths as int
set #FirstRepair = (<Select statement to find first repair across all records>)
set #CountMonths = (<select statement to find the number of months between the first repair across all records and today>)
--clear out the scratch table
delete from dbo.tblMonthEndDate
set #counter=0
while #counter <=#CountMonths --fill the scratch table with the date of the last day of every month from the #FirstRepair till today
begin
insert into dbo.tblMonthEndDate(monthenddate) select dbo.lastofmonth(dateadd(m,#counter, #FirstRepair))
set #counter = #counter+1
end
--set up a CTE to get a cross join between the scratch table and the view that has the associated first Failed Inspection and Repair
;with Drepairs_CTE (FacilityID, TagNumber, CompType, EventDate)
AS
(
SELECT dbo.vwDelayedRepairWithRepair.FacilityID, dbo.vwDelayedRepairWithRepair.TagNumber, dbo.vwDelayedRepairWithRepair.CompType,
dbo.tblMonthEndDate.MonthEndDate
FROM dbo.vwDelayedRepairWithRepair INNER JOIN
dbo.tblMonthEndDate ON dbo.vwDelayedRepairWithRepair.EventDate <= dbo.tblMonthEndDate.MonthEndDate AND
dbo.vwDelayedRepairWithRepair.RepairDate >= dbo.tblMonthEndDate.MonthEndDate
)
--use the CTE to build the final table I want
Select FacilityID, CompType, Count(TagNumber), MONTH(EventDate), YEAR(EventDate), 'zzz' as EventLabel
FROM Drepairs_CTE
GROUP BY FacilityID, CompType, MONTH(EventDate), YEAR(EventDate)`
Result set ultimately looks like this:
FacilityID CompType Count Month Year Label
1 xyz 2 1 2010 zzz
1 xyz 1 2 2010 zzz
1 xyz 1 7 2009 zzz
Here is a recursive CTE which generates table of last dates of months in interval starting with minimum date in repair table and ending with maximum date.
;with tableOfDates as (
-- First generation returns last day of month of first date in repair database
-- and maximum date
select dateadd (m, datediff (m, 0, min(eventDate)) + 1, 0) - 1 startDate,
max(eventDate) endDate
from vwDelayedRepairWithRepair
union all
-- Last day of next month
select dateadd (m, datediff (m, 0, startDate) + 2, 0) - 1,
endDate
from tableOfDates
where startDate <= endDate
)
select *
from tableOfDates
-- If you change the CTE,
-- Set this to reasonable number of months
-- to prevent recursion problems. 0 means no limit.
option (maxrecursion 0)
EndDate column from tableOfDates is to be ignored, as it serves as upper bound only. If you create UDF which returns all the dates in an interval, omit endDate in select list or remove it from CTE and replace with a parameter.
Sql Fiddle playground is here.

Resources