Scripting the latest month in the data set [closed] - sql

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
In the following view,instead of specifying the actual dates in the where condition,I want sql server to recognize June and May as the latest month and the (latest month-1) as the view gets refreshed on a monthly basis and so does latest month and (latest month -1).
PS:- The latest Report month is June in the table
SELECT (A.[First Name])
,A.[Last Name]
,A.[Report Month]
FROM (
(
SELECT DISTINCT [First Name]
,[Last Name]
,[Report Month]
,[Bill To Code]
,[Region]
,[Area]
FROM dbo.Data
WHERE (
[Report Month] BETWEEN '2015-06-01'
AND '2015-06-30'
AND [FTE Status] = 'Inactive'
)
) A INNER JOIN (
SELECT DISTINCT [First Name]
,[Last Name]
,[Report Month]
,[Bill To Code]
,[Region]
,[Area]
FROM dbo.Data
WHERE (
[Report Month] BETWEEN '2015-05-01'
AND '2015-05-31'
AND [FTE Status] = 'Active'
)
) B ON A.[First Name] = B.[First Name]
AND A.[Last Name] = B.[Last Name]
)
Thank you,just learnt how to format better in SO.Thanks to Sean.Learning from my mistakes guys..:)

Hence i should write some function so that sql server reads the start
and end date of the latest month in the data set.
You say you need to read the start and end date, but if what you really need is just to get all the data that is in the latest month in your table, then this will do it:
select *
from dbo.Data
where DATEDIFF(month,[Report Month],(SELECT MAX([Report Month] FROM dbo.Data))=0
and [FTE Status]='Active'

Despite your rather vague question, I think this is what you are looking for.
This will return the first and last day for the max date in YourTable.
;with cte as (
select convert(date,left(convert(varchar,Max(Report_Month),112),6) + '01') startDate,
month(Max(Report_Month)) n
from YourTable
union all
select dateadd(month,n,convert(date,convert(varchar,year(startDate)) + '0101')) startDate,
(n+1) n
from cte
where n < month(startDate)
)
select startdate, dateadd(day,-1,dateadd(month,1,startdate)) enddate
from cte

How about:
SELECT MAX(MONTH(Report_Month))
FROM YourTable
GROUP BY YEAR(Report_Month)
HAVING YEAR(Report_Month) = MAX(YEAR(Report_Month))

Related

SQL find the oldest date from a range of dates where attributes repeat from month to month

Need help isolating the oldest date from a table where the following attributes:[process id],[tracking id],[bp] are identical in the previous months.
I run a recon report once a month. Need to identify if records in this month Recon Report appeared in previous months. If the record appeard in a previous report than I need to identify the oldest date an Issue has been opened, so I can identify delinquents. The last time the report ran was 6/31/2020, but the issue has been open for the last three months.
Here are the results that I would I like to see.
Below is they query that I am running.
declare #date datetime
set #date= '6/30/2020'
select
DATEDIFF(d,date, #date) as [Number of days outstanding],
[Business Profile Name],
[Unit],
[Tracking ID],
[Owner],
[Issue]
from
[Recon_Report]
where
concat ([process id],[tracking id],[bp]) in
(
select
(concat ([process id],[tracking id],[bp]))
from
[Recon_Report]
where
date = #date
)
and date < #date
order by [process id],[tracking id],[bp], Date asc
I tried adding this to query:
min(DATEDIFF(d,date, #date))
But I get an error mesage:
Msg 8120, Level 16, State 1, Line 19
Column 'Recon_Report.Date' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
Just use window functions. I think you want:
select DATEDIFF(d,date, #date) as [Number of days outstanding],
rr.*
from (select rr.*,
max(case when date = #date then 1 else 0 end) over (partition by [process id], [tracking id], [bp]) as on_date,
dense_rank() over (partition by [process id], [tracking id], [bp] order by date) as seqnum
from Recon_Report rr
where date <= #date
) rr
where seqnum = 1
order by [process id], [tracking id], [bp], Date asc
Here is a solution that worked for me.
declare #date datetime
set #date= '6/30/2020'
select
DATEDIFF(d,min(date), #date) as [Number of days outstanding],
[Business Profile Name],
[Unit],
[Tracking ID],
[Owner],
[Issue]
from
[Recon_Report]
where
concat ([process id],[tracking id],[bp]) in
(
select
(concat ([process id],[tracking id],[bp]))
from
[Recon_Report]
where
date = #date
)
and date < #date
group by
[Business Profile Name],
[Unit],
[Tracking ID],
[Owner],
[Issue]

How to select max date over the year function

I am trying to select the max date over the year, but it is not working. Any ideas on what to do?
SELECT a.tkinit [TK ID],
YEAR(a.tkeffdate) [Rate Year],
max(a.tkeffdate) [Max Date],
tkrt03 [Standard Rate]
FROM stageElite.dbo.timerate a
join stageElite.dbo.timekeep b ON b.tkinit = a.tkinit
WHERE a.tkinit = '02672'
and tkeffdate BETWEEN '2014-01-01' and '12-31-2014'
GROUP BY a.tkinit,
tkrt03,
a.tkeffdate
Perhaps you only want it by year and not rolled up by calendar date. For SQL server you can try this.
SELECT
…
MaxDate = MAX(a.tkeffdate) OVER (PARTITION BY a.tkinit, YEAR(a.tkeffdate)))
…
Or you could modify the query above to group by the year instead of date-->
GROUP BY a.tkinit,
tkrt03,
YEAR(a.tkeffdate)
You seem to want only one row and all the columns. Use ORDER BY and TOP:
SELECT TOP (1) tr.tkinit as [TK ID],
YEAR(tr.tkeffdate) as [Rate Year],
a.tkeffdate as [Max Date],
tkrt03 as [Standard Rate]
FROM stageElite.dbo.timerate tr JOIN
stageElite.dbo.timekeep tk
ON tk.tkinit = tr.tkinit
WHERE tr.tkinit = '02672' AND
tr.tkeffdate >= '2014-01-01' AND
tr.tkeffdate < '2015-01-01'
ORDER tr.tkeffdate DESC;
Note that I also fixed your date comparisons and table aliases.

New to SQL. Would like to convert an IF(COUNTIFS()) Excel formula to SQL code and have SQL calculate it instead of Excel

I am running SQL Server 2008 R2 (RTM).
I have a SQL query that pulls Dates, Products, Customers and Units:
select
[Transaction Date] as Date,
[SKU] as Product,
[Customer Name] as Customer,
sum(Qty) as Units
from dataset
where [Transaction Date] < '2019-03-01' and [Transaction Date] >= '2016-01-01'
group by [Transaction Date], [SKU], [Customer Name]
order by [Transaction Date]
This pulls hundreds of thousands of records and I wanted to determine if a certain transaction was a new order or reorder based on the following logic:
Reorder: That specific Customer has ordered that specific product in the last 6 months
New Order: That specific Customer hasn’t ordered that specific product in the last 6 months
For that I have this formula in Excel that seems to be working:
=IF(COUNTIFS(A$1:A1,">="&DATE(YEAR(A2),MONTH(A2)-6,DAY(A2)),C$1:C1,C2,B$1:B1,B2),"Reorder","New Order")
The formula works when I paste it individually or in a smaller dataset, but when I try to copy paste it to all 500K+ rows, Excel gives up because it loops for each calculation.
This could probably be done in SQL, but I don’t have the knowledge on how to convert this excel formula to SQL, I just started studying it.
You're doing pretty well with the start of your query there. There are three additional functions you're looking to add to your query.
The first thing you'll need is the easiest. GETDATE() simply returns the current date. You'll need that when you're comparing the current date to the transaction date.
The second function is DATEDIFF, which will give you a unit of time between two dates (months, days, years, quarters, etc). Using DATEDIFF, you can say "is this date within the last 6 months". The format for this is pretty easy. It's DATEDIFF(interval, date1, date2).
The thrid function you're looking for is CASE, which allows you to tell SQL to give you one answer if one condition is met, but a different answer if a different condition is met. For your example, you can say "if the difference in days is < 60, return 'Reorder', if not give me 'New Order'".
Putting it all together:
SELECT CASE
WHEN DATEDIFF(MONTH, [Transaction Date], GETDATE()) <= 6
THEN 'Reorder'
ELSE 'New Order'
END as ORDER_TYPE
,[Transaction Date] AS DATE
,[SKU] AS PRODUCT
,[Customer Name] AS CUSTOMER
,Qty AS UNITS
FROM DATASET
For additonal examples on CASE, take a look at this site: https://www.w3schools.com/sql/sql_ref_case.asp
For additional examples on DATEDIFF, take a look here: See the
following webpage for examples and a chance to try it out:
https://www.w3schools.com/sql/func_sqlserver_datediff.asp
SELECT CASE
WHEN Datediff(day, [transaction date], Getdate()) <= 180 THEN 'reorder'
ELSE 'Neworder'
END,
[transaction date] AS Date,
[sku] AS Product,
[customer name] AS Customer,
qty AS Units
FROM datase
If I understand correctly, you want to peak at the previous date and make a comparison. This suggests lag():
select (case when lag([Transaction Date]) over (partition by SKU, [Customer Name] order by [Transaction Date]) >
dateadd(month, -6, [Transaction Date])
then 'Reorder'
else 'New Order'
end) as Order_Type
[Transaction Date] as Date,
[SKU] as Product,
[Customer Name] as Customer,
sum(Qty) as Units
from dataset d
group by [Transaction Date], [SKU], [Customer Name];
EDIT:
In SQL Server 2008, you can emulate the LAG() using OUTER APPLY:
select (case when dprev.[Transaction Date] >
dateadd(month, -6, d.[Transaction Date])
then 'Reorder'
else 'New Order'
end) as Order_Type
d.[Transaction Date] as Date,
d.[SKU] as Product,
d.[Customer Name] as Customer,
sum(d.Qty) as Units
from dataset d outer apply
(select top (1) dprev.*
from dataset dprev
where dprev.SKU = d.SKU and
dprev.[Customer Name] = d.[Customer Name] and
dprev.[Transaction Date] < d.[Transaction Date]
order by dprev.[Transaction Date] desc
) dprev
group by d.[Transaction Date], d.[SKU], d.[Customer Name];

Converting Different columns into rows in SQL Server

I have data in SQL Server that needs to be converted from columns into rows. Now although this question has been asked quite a lot in sometime, I was still facing some difficulty and hence I was wondering if someone can assist me.
Currently the format is as below.
The table format that is required and that will be very helpful will be;
So not only the PIVOT needs to be applied but I am not sure which SQL Query syntax will help to identify the Type. I have tried using CASE-WHEN with PIVOT but that really yield correct output.
Regards!
You can use CROSS APPLY query like below
see working demo
Select
ProjectName,
v.*
from t
cross apply
(
values
('Plan',PlanStartDate,PlanEndDate),
('Actual',ActualStartDate, ActualEndDate)
)v(type,StartDate, EndDate)
Try this
;WITH CTE2(ProjectName,[Plan Start Date],[Plan End Date],[Actual Start Date],[Actual End Date])
AS
(
SELECT 'PR-A','1/1/2006','1/4/2006','1/4/2007','1/5/2008' UNION ALL
SELECT 'PR-B','1/1/2007','1/1/2008','4/4/2008','6/6/2008' UNION ALL
SELECT 'PR-C','1/1/2004','1/1/2008','2/5/2001','2/2/2008'
)
SELECT Projectname,
'Plan' AS [Type],
[Plan start date] AS [Start Date],
[Plan end date] AS [End Date]
FROM Cte2
UNION ALL
SELECT Projectname,
'Actual' AS [Type],
[Actual start date],
[Actual end date]
FROM Cte2
ORDER BY Projectname,
[Type] DESC
Demo :http://rextester.com/CQEBV76844

Sql Query with inner select [duplicate]

This question already has answers here:
Sql query to create a calculated field
(2 answers)
Closed 8 years ago.
I have this sql query:
SELECT DISTINCT
[Card NO],
[User Name],
(
SELECT
MIN(DateTime) AS [Enter Time],
MAX(DateTime) AS [Exit Time],
MAX(DateTime) - MIN(DateTime) AS [Inside Hours]
FROM
ExcelData
)
FROM
ExcelData
GROUP BY
[Card NO], [User Name], DateTime
Table Schema: CardNO | UserName | DateTime
I tried to execute it but with no success. I says that it is an invalid query.
Can anyone find what is wrong in this query?
This would not resolve your possible Problems with reserved keywords and column names, but should be a valid query. You were using a select query as column Name.
SELECT
[Card NO],
[User Name],
MIN(DateTime) AS [Enter Time],
MAX(DateTime) AS [Exit Time],
MAX(DateTime) - MIN(DateTime) AS [Inside Hours]
FROM
ExcelData
GROUP BY
[Card NO], [User Name]
You are grouping by DateTime, which is a reserved keyword, and you don't select a column DateTime. You do select aggregates over DateTime, which means you shouldn't group on it. #irene got the right answer.