How to select same data of previous year?
IN SQL Server use DATEADD:
SELECT a.ARRDate,
a.SomeData, --Current
b.SomeData --Previous
FROM MyTable a
LEFT JOIN MyTable b
ON DATEADD(year,-1,a.ARRDate) = b.ARRDate
Join your table with itself.
Related
I have data that looks like this where there is a monthly count of a particular animal for each month. By default, it aggregates in the month where there is data.
However, I would like to like to have a default set of dates for each animal up to the current month date with 0 if there's no data. Desired Result -
Is there a way to handle with a on sql server and not in Excel?
Much appreciated in advance.
You can generate the months you want using a numbers table or recursive CTE (or calendar table). Then cross join with the animals to generate the rows and use left join to bring in the existing data:
with dates as (
select min(date) as dte
from t
union all
select dateadd(month, 1 dte)
from dates
where dte < getdate()
)
select a.animal, d.dte, coalesce(t.monthly_count, 0) as monthly_count
from dates d cross join
(select distinct animal from t) a left join
data t
on t.date = d.dte and t.animal = a.animal
order by a.animal, d.dte;
I have a data table, which consist of 4 dates per string:
table example
Also I have calendar table with holidays and weekends for my location.
calendar table
What I need is to count number of working days for following pairs in data table:
task_work_end_date and task_got_to_work_date
task_got_to_work_date and task_assigned_date
I have tried following select, but it would always show 1 working day, because I'm putting calendar_date in front:
select data_table.*, days.work_days
from data_table
left join (
select calendar_date, count(calendar_date) as work_days
from calendar_table
where type_of_day IN ('workday', 'workday shortened')
group by calendar_date ) days
ON days.calendar_date between task_assigned_date and task_got_to_work_date
Please advise on SQL to achieve correct joining those tables.
If you are on SQL server then use OUTER APPLY as follows:
select d.*, days.work_days
from data_table d
outer apply (
select count(calendar_date) as work_days
from calendar_table c
where c.type_of_day IN ('workday', 'workday shortened')
and c.calendar_date between d.task_assigned_date and d.task_got_to_work_date) days
A lateral join is definitely one way to solve the problem (that is the apply syntax in the other answers).
A more generic answer is simply a correlated subquery:
select d.*,
(select count(*)
from calendar_table c
where c.type_of_day in ('workday', 'workday shortened') and
c.calendar_date between d.task_assigned_date and d.task_got_to_work_datework_days
) as work_days
from data_table d;
Note: If performance is an issue, there may be other approaches. If that is the case, accept one of the answers here and ask a new question.
To use a left join, you need to change how you are grouping. You can list the actual columns in data_table in the group by and the select as well.
select data_table.*, count(days.calendar_date)
from data_table
left join calendar_table days
ON days.calendar_date between task_assigned_date and task_got_to_work_date
and type_of_day IN ('workday', 'workday shortened')
group by data_table.*
Another option would be to outer apply and get the count this way:
select data_table.*, days.work_days
from data_table
outer apply (
select count(calendar_date) as work_days
from calendar_table
where type_of_day IN ('workday', 'workday shortened')
and calendar_date between task_assigned_date and task_got_to_work_date) days
Solution worked perfectly for me in POSTGRES:
table example
join
calendar table ON tsrange(task_assigned_date, task_got_to_work_date)&&tsrange(calendar.start_time, calendar.end_time)
I would like to select dynamically all entries from last two months, and without entering date range in my query.
Here is my simple code:
SELECT Customer_Name, Date FROM table_Customer; all data between last two month
Thanks in advance for your help
SELECT
ME.FullName,
R.RuleDefaultName,
PR.ObjectName,
PR.CounterName,
P.DateTime,
P.SampleCount,
P.MinValue,
P.MaxValue,
P.AverageValue,
P.StandardDeviation
FROM
Perf.vPerfHourly P
INNER JOIN vManagedEntity ME ON
P.ManagedEntityRowId = ME.ManagedEntityRowId
INNER JOIN vPerformanceRuleInstance PRI ON
P.PerformanceRuleInstanceRowId = PRI.PerformanceRuleInstanceRowId
INNER JOIN vPerformanceRule PR ON
PRI.RuleRowId = PR.RuleRowId
INNER JOIN vRule R ON
PRI.RuleRowId = R.RuleRowId
SELECT Customer_Name, Dt
FROM table_Customer
where dt >= dateadd(day, -60, getdate())
Or
SELECT Customer_Name, Dt
FROM table_Customer
where dt >= dateadd(month, -2, getdate())
You should make sure not to use reserved keywords as column names.
Make sure you replace dt with the appropriate date column. The solution assumes you would need the previous 2 months data starting with the current date.
Select *
From Customers
Where
OrderDate between Dateadd(M,-2,OrderDate) And Getdate()
I have a table with dates that are about 1 month before the other table.
For example,
one table reports 1st quarter end on March 31st
and the other reports 1st quarter end on February 28th (or 29th)
but it would be perfectly fine to join them together by the date regardless that the two dates arent exactly the same.
Any suggestions, please.
Thanks
You can join on DateDiff(dd, Date1, Date2) < x
Or to get more exact
select endOfMonth.*, begOfMonth.*
from endOfMonth join begOfMonth
on DATEADD (dd , 1 , endOfMonth.date ) = begOfMonth.Date
Your ON clause could look at year and quarter for a match:
ON TABLE1.YEAR([1st quarter end ]) = TABLE2.YEAR([1st quarter end ])
AND TABLE1.QUARTER([1st quarter end ]) = TABLE2.QUARTER([1st quarter end ])
select val1 From Table1 T1 inner Join Table2 t2 on MONTH(T1.date1) = MONTH(t2.date1)
And YEAR(T1.date1) = YEAR(t2.date1)
One approach would be to use the DATEPART() function that returns the quarter for any given date. Then you would be able to join on the returned quarter.
Sample SQL:
SELECT *
FROM
(
SELECT DATEPART(QUARTER,date_column) AS t1_quarter
FROM table1
UNION ALL
SELECT DATEPART(QUARTER,date_column) AS t2_quarter
FROM table2
) AS temp
WHERE temp.t1_quarter = temp.t2_quarter;
Put any other fields as you require (ID fields most probably) in the internal SELECTS.
If I rigthly understood you and you have the same number of column in those tables then you should use UNION in your SQL-query. See more information about UNION here: http://en.wikipedia.org/wiki/Set_operations_%28SQL%29.
I have a database table with the following structure -
Week_End Sales
2009-11-01 43223.43
2009-11-08 4324.23
2009-11-15 64343.23
...
Week_End is a datetime column, and the date increments by 7 days with each new entry.
What I want is a SQL statement that will identify if there is a week missing in the sequence. So, if the table contained the following data -
Week_End Sales
2009-11-01 43223.43
2009-11-08 4324.23
2009-11-22 64343.73
...
The query would return 2009-11-15.
Is this possible? I am using SQL Server 2008, btw.
You've already accepted an answer so I guess you don't need this, but I was almost finished with it anyway and it has one advantage that the selected solution doesn't have: it doesn't require updating every year. Here it is:
SELECT T1.*
FROM Table1 T1
LEFT JOIN Table1 T2
ON T2.Week_End = DATEADD(week, 1, T1.Week_End)
WHERE T2.Week_End IS NULL
AND T1.Week_End <> (SELECT MAX(Week_End) FROM Table1)
It is based on Andemar's solution, but handles the changing year too, and doesn't require the existence of the Sales column.
Join the table on itself to search for consecutive rows:
select a.*
from YourTable a
left join YourTable b
on datepart(wk,b.Week_End) = datepart(wk,a.Week_End) + 1
-- No next week
where b.sales is null
-- Not the last week
and datepart(wk,a.Week_End) <> (
select datepart(wk,max(Week_End)) from YourTable
)
This should return any weeks without a next week.
Assuming your "week_end" dates are always going to be the Sundays of the week, you could try a CTE - a common table expression that lists out all the Sundays for 2009, and then do an outer join against your table.
All those rows missing from your table will have a NULL value for their "week_end" in the select:
;WITH Sundays2009 AS
(
SELECT CAST('20090104' AS DATETIME) AS Sunday
UNION ALL
SELECT
DATEADD(DAY, 7, cte.Sunday)
FROM
Sundays2009 cte
WHERE
DATEADD(DAY, 7, cte.Sunday) < '20100101'
)
SELECT
sun.Sunday 'Missing week end date'
FROM
Sundays2009 sun
LEFT OUTER JOIN
dbo.YourTable tbl ON sun.Sunday = tbl.week_end
WHERE
tbl.week_end IS NULL
I know this has already been answered, but can I suggest something really simple?
/* First make a list of weeks using a table of numbers (mine is dbo.nums(num), starting with 1) */
WITH AllWeeks AS (
SELECT DATEADD(week,num-1,w.FirstWeek) AS eachWeek
FROM
dbo.nums
JOIN
(SELECT MIN(week_end) AS FirstWeek, MAX(week_end) as LastWeek FROM yourTable) w
ON num <= DATEDIFF(week,FirstWeek,LastWeek)
)
/* Now just look for ones that don't exist in your table */
SELECT w.eachWeek AS MissingWeek
FROM AllWeeks w
WHERE NOT EXISTS (SELECT * FROM yourTable t WHERE t.week_end = w.eachWeek)
;
If you know the range you want to look over, you don't need to use the MIN/MAX subquery in the CTE.