I'm using Microsoft SQL Server and have 2 tables, AbsenceHistory and FITNoteHistory.
AbsenceHistory:
[Employee Number], [Absence Number], [Start Date], [End Date]
FITNoteHistory:
[Absence Number], [FIT Note Number], [Start Date], [End Date]
I need to identify where there is a gap in the FIT Note History, that doesn't cover the entire Absence Period between DateAdd(d,7,AbsenceHistory.[Start Date]) and AbsenceHistory.[End Date], where AbsenceHistory.[End Date] is not null and DATEDIFF(d,AbsenceHistory.[Start Date],AbsenceHistory.[End Date]) >= 7.
The output needs to give me the actual date gaps for each absence.
E.g. Absence Number, Date of Gap
Can anyone help?
Example Data:
AbsenceHistory:
[Employee Number], [Absence Number], [Start Date], [End Date]
18615, 70, '01-Jan-2018', '31-Jan-2018'
FITNoteHistory:
[Absence Number], [FIT Note Number], [Start Date], [End Date]
70, 1, '08-Jan-2018', '15-Jan-2018'
70, 15, '18-Jan-2018', '24-Jan-2018'
70, 31, '26-Jan-2018', '01-Feb-2018'
My expected output would be:
[Employee Number], [Absence Number], [Gap Date]
18615, 70, '16-Jan-2018'
18615, 70, '17-Jan-2018'
18615, 70, '25-Jan-2018'
This should get you started
declare #t table ([Absence Number] int, [FIT Note Number] int, [Start Date] date, [End Date] date)
insert into #t values
(70, 1, '08-Jan-2018', '15-Jan-2018')
, (70, 15, '18-Jan-2018', '24-Jan-2018')
, (70, 31, '26-Jan-2018', '01-Feb-2018');
select t.[Absence Number], t.[FIT Note Number], t.[Start Date], t.[End Date]
from #t t
order by t.[Start Date], t.[End Date], t.[FIT Note Number];
declare #minDate date = (select min([End Date]) from #t);
declare #maxDate date = (select max([Start Date]) from #t);
with cteDate as
(
select #minDate as dDate
union all
select cast(dateadd(dd, 1, dDate) as date)
from cteDate
where dDate < #maxDate
)
, cteNext as
( select t.[Absence Number], t.[FIT Note Number], t.[Start Date], t.[End Date]
, lead(t.[Start Date], 1) OVER (ORDER BY t.[Start Date]) AS nextStart
from #t t
)
select n.[Absence Number], n.[FIT Note Number], n.[Start Date], n.[End Date]
, d.dDate
from cteNext n
join cteDate d
on d.dDate > n.[End Date]
and d.dDate < n.nextStart
order by d.dDate;
Related
I have checked Temp_Calc_1 against Temp_Calc_2 and they both have the same column datatypes (float, nvarchar(255)) and are in the same order when reading down the table. When I try to run this on the empty Temp_Calc_2, I get an error:
Error converting nvarchar to float
on the line INSERT INTO dbo.Temp_Calc_2
USE MfgMetrics
INSERT INTO dbo.Temp_Calc_2
SELECT
zps.[Plant], [Work Center],
[Scheduled start Date], [SCHEDULE START TIME],
[SCHEDULED FINISHED DATE], [SCHEDULED FINISHED TIME],
[MATERIAL NUMBER], [MATERIAL DESCRIPTON],
[ORDER NUMBER], [ORDER TYPE],
[PLANNED QUANTITY], [PLANNED QTY - PROD UN],
[DELIVERED QTY], [DELIVERED QTY - PROD UN],
[RemainingQty(BUn)], [REMAINING QTY - Prod Un],
[COMMITED QTY], [COMMITED QTY - PROD UN], [UOM],
[STORAGE LOCATION], [COMMENTS],
[RATE QUANTITY], [RATE QUANTITY - PROD UN], [RATE HOUR],
[OPERATING EFFIECIENCY], [UNIT],
[STD UNITS / HR], [STD UNITS / HR - PROD UN], [UOM2],
[ORDER STATUS], [ACTUAL START DATE], [ACTUAL START TIME],
[MRP CONTROLLER], [CREATED ON], [TIME CREATED],
[CHANGED ON], [TIME CHANGE],
[ORDER TEXT LINES], [ORDER TEXT 2nd LINE], [FileDate],
scf.[OQ_RxnTime_(mins)], scf.[RunDurThreshold_(hrs)],
CASE
WHEN (zps.[MATERIAL NUMBER] LIKE '%.%')
THEN zps.[MATERIAL NUMBER]
WHEN ISNUMERIC(zps.[MATERIAL NUMBER]) = 1
THEN CAST(CAST(zps.[MATERIAL NUMBER] AS INT) AS NVARCHAR(255))
ELSE zps.[MATERIAL NUMBER]
END As [Material],
(CAST(CAST(zps.[ORDER NUMBER] AS INT) AS NVARCHAR(255)) + '_' + CAST(CAST(zps.[PLANNED QUANTITY] AS INT) AS NVARCHAR(255))) AS Order_Quantity,
scf.[OQ_RxnTime_(mins)] * zps.[STD UNITS / HR] / 60 AS OQWindow
FROM
Temp_Calc_1 zps
INNER JOIN
SAWorkCenters swc ON zps.Plant = swc.Plant
AND zps.[Work Center] = swc.WCGroup
INNER JOIN
SchedAttCalcFactors scf ON zps.Plant = scf.[Plant Code]
ORDER BY
zps.Plant, zps.[Work Center], zps.[ORDER NUMBER], zps.FileDate
GO
I have a table and query as follow:
I am trying to get overlapping records between [Assignment Start Date] and [Assignment End Date] for same Employee Id.
In short I need data for those Employee Id which are allocated for same time period or overlapping time period from below example.
e.g.
[Employee Id] [Assignment Start Date] [Assignment End Date] [Allocation Percentage]
100 2016-03-01 2017-02-28 100
102 2016-06-01 2016-12-31 100
102 2016-07-01 2016-10-30 100
102 2016-11-01 2017-01-31 100
103 2017-02-01 2017-05-30 100
102 2017-04-01 2017-06-30 100
102 2017-11-01 2017-01-31 100
104 2017-02-01 2017-05-01 100
CREATE TABLE #Result
(
PK INT IDENTITY(1,1),
[BU] VARCHAR(20),
[Division] VARCHAR(20),
[Product Name] VARCHAR(30),
[Employee ID] NVARCHAR(20),
[Resource Name] VARCHAR(50),
[Resource_ID] INT,
[Assignment Start Date] DATE,
[Assignment End Date] DATE,
[Allocation Percentage] INT,
[Location] VARCHAR(100),
[Development Manager] VARCHAR(50),
[Allocation] VARCHAR(20)
);
SELECT DISTINCT r1.PK, r1.Resource_ID,r1.[Employee ID], r1.[Assignment Start Date] AS 'Start 1' ,r1.[Assignment End Date] AS 'End 1' , r2.[Assignment Start Date] , r2.[Assignment End Date]
INTO #temp1
FROM #Result r1
INNER JOIN #Result r2
ON r1.[Employee ID] = r2.[Employee ID]
AND (r1.PK <> r2.PK)
AND ((r1.[Assignment Start Date] <= r2.[Assignment Start Date]) AND (r1.[Assignment End Date] >= r2.[Assignment Start Date]))
OR ((r1.[Assignment Start Date] > r2.[Assignment Start Date] AND r1.[Assignment Start Date] <= r2.[Assignment End Date]) AND (r1.[Assignment End Date] <= r2.[Assignment End Date]))
OR ((r1.[Assignment Start Date] > r2.[Assignment Start Date] AND r1.[Assignment Start Date] <= r2.[Assignment End Date]) AND (r1.[Assignment End Date] > r2.[Assignment End Date]))
OR (r1.[Assignment Start Date] = r2.[Assignment End Date])
I have tried using above query but it gives all records related to overlapping employee even if that entry for that employee is not overlapping.
In above example there is a Employee Id 102 which has 2 overlapping entries and 3rd entry which is not overlapping I want to remove it from this result. please help.
CTE, row_number and a self join
with CTE as
(
select PK, Resource_ID, [Employee ID] as Emp_ID, [Assignment Start Date] as s_Date, [Assignment End Date] as e_date,
row_number() over(partition by [Employee ID] order by [Assignment Start Date] ) as rn
from #Result
)
select t1.*, t2.*
from CTE t1
inner join CTE t2
on t1.Resource_ID = t2.Resource_ID
and t1.Emp_ID = t2.Emp_ID
and t2.rn = t1.rn +1
where t2.s_date <= t1.e_date
or t1.e_date is null -- allows for null end date
Your SQL query should look like that below:
SELECT DISTINCT r1.PK, r1.Resource_ID,r1.[Employee ID], r1.[Assignment Start Date] AS 'Start 1' ,r1.[Assignment End Date] AS 'End 1' , r2.[Assignment Start Date] , r2.[Assignment End Date]
INTO #temp1
FROM #Result r1
JOIN #Result r2 on r1.[Employee ID] = r2.[Employee ID]
WHERE (
(r2.[Assignment Start Date] BETWEEN r1.[Assignment Start Date] and r1.[Assignment End Date])
or
(r2.[Assignment End Date] between p1.[Assignment Start Date] and p1.[Assignment End Date])
)
AND r1.PK <> r2.PK
I'm trying to create one sql table with the current week's data (always changing) as well as those dates data from the previous year. I have multiple tables that I have to join but am not sure how to create it all into one table. Here is what I have so far:
------- CURRENT YEAR -------
DECLARE
#CURRENTDATE DATE,
#BEGINDATE DATE
SET #CURRENTDATE = CONVERT(DATE,GETDATE()) ---// TODAY'S DATE //---
SET #BEGINDATE = DATEADD(DAY, -7, GETDATE()) ---// A WEEK BEFORE TODAY'S DATE //---
SELECT SALES.*, RECRUITS.Recruits
FROM
(
SELECT
CONVERT(VARCHAR(10), A.[ORDER DATE], 101) AS 'DAY'
, 'Sales Revenue Current Year' = FORMAT(SUM(A.[GRAND TOTAL]) ,'C', 'EN-US')
, 'Comm. Sales Volume Current Year' = FORMAT(sum(a. [QUALIFYING VOLUME]), 'C', 'EN-US')
FROM TABLE1 a
WHERE CONVERT(VARCHAR(10), A.[ORDER DATE], 101) >= #BEGINDATE AND CONVERT(VARCHAR(10), A.[ORDER DATE], 101) < #CURRENTDATE
GROUP BY CONVERT(VARCHAR(10), A.[ORDER DATE], 101)
) SALES,
(
SELECT
CONVERT(VARCHAR(10),a.[start date],101) AS 'DAY'
,count(b.[id number]) as Recruits
from TABLE2 a
left join
TABLE3 b
on a.enroller = b. [id number]
WHERE CONVERT(VARCHAR(10), A.[START DATE], 101) >= #BEGINDATE AND CONVERT(VARCHAR(10), A.[START DATE], 101) < #CURRENTDATE
group by a.[start date]
) RECRUITS
WHERE SALES.DAY = RECRUITS.DAY
I have the same script for the previous year. It is the same except I set the dates to -366 and -373 days. Any help would be great!
You can use multiple dates with an "OR", like below, but a better solution would be to use a date dimensional table, a list of every daily date with things like "WeekOfYear", "WeekOfMonth", "QuarterOfYear", "IsHoliday", etc. Then you can join your date against that table and query "where t1.WeekOfYear = t2.WeekOfYear".
DECLARE
#EndDate DATE = GETDATE() ---// TODAY'S DATE //---
, #StartDate DATE = DATEADD(DAY, -7, GETDATE()) ---// A WEEK BEFORE TODAY'S DATE //---
, #LYStartDate DATE = DATEADD(YEAR, -1, GETDATE()) ---// A YEAR BEFORE TODAY'S DATE //---
, #LYEndDate DATE = DATEADD(DAY, -7, DATEADD(YEAR, -1, GETDATE())) ---// A YEAR AND A WEEK BEFORE TODAY'S DATE //---
SELECT SALES.*, RECRUITS.Recruits
FROM
(
SELECT
'DAY' = CONVERT(VARCHAR(10), A.[ORDER DATE], 101)
, 'Sales Revenue Current Year' = FORMAT(SUM(A.[GRAND TOTAL]) ,'C', 'EN-US')
, 'Comm. Sales Volume Current Year' = FORMAT(sum(a. [QUALIFYING VOLUME]), 'C', 'EN-US')
FROM TABLE1 a
WHERE (
(CAST(A.[ORDER DATE] AS DATE) >= #StartDate AND CAST(A.[ORDER DATE] AS DATE) <= #EndDate)
OR
(CAST(A.[ORDER DATE] AS DATE) >= #LYStartDate AND CAST(A.[ORDER DATE] AS DATE) <= #lyEndDate)
)
GROUP BY CAST(A.[ORDER DATE] AS DATE)
) SALES,
(
SELECT
'DAY' = CAST(a.[start date] AS DATE)
, Recruits = COUNT(b.[id number])
FROM TABLE2 a
LEFT JOIN TABLE3 b
ON a.enroller = b. [id number]
WHERE (
(CAST(A.[START DATE] AS DATE) >= #StartDate AND CAST(A.[ORDER DATE] AS DATE) <= #EndDate)
OR
(CAST(A.[START DATE] AS DATE) >= #lyStartDate AND CAST(A.[ORDER DATE] AS DATE) <= #LYEndDate)
GROUP BY CAST(a.[start date] AS DATE)
) RECRUITS
WHERE SALES.DAY = RECRUITS.DAY
I have table variable that I fill with all dates between a particular range (and the dw,wk,mm,yy,dd values)
I then join this to my inspection records by the start date.
SELECT CalDate
, DayN
, WeekN
, YearN
, DayOfMonthN
, [Start Date]
, [End Date]
, [Inspection Number]
FROM #Calendar AS dateInfo
LEFT JOIN [Inspection Records] AS IR
ON IR.[Start Date] = dateInfo.CalendarDate
This works fine, what I am now needing to do (and i have to do it this way to pass to a 3rd party application...) is get all the dates between the [Start Date] and [End Date] and add them into a column as a comma separated list.
I've come across this answer t-sql get all dates between 2 dates
that seems to get the dates perfectly for what I need.
I'm stuck on how to structure my script to use that script to get all the dates between my [Start Date] and [End Date] and add them into a column.
what is the best way to calculated all dates between my two columns
how to insert the outcome into a single column as comma separated list
NOTE: I can not add anything to the database.
Example: (Trying to get the dates column)
<table>
<tr>
<td>CalDate</td>
<td>DayN</td>
<td>WeekN</td>
<td>YearN</td>
<td>DayOfMonthN</td>
<td>Start Date</td>
<td>End Date</td>
<td>Inspection Number</td>
<td>Dates</td>
</tr>
<tr>
<td>07-08-2014</td>
<td>5</td>
<td>32</td>
<td>2014</td>
<td>7</td>
<td>07-08-2014</td>
<td>11-08-2014</td>
<td>A0001</td>
<td>07-08-2014,08-08-2014,09-08-2014,10-08-2014,11-08-2014</td>
</tr>
</table>
SELECT CalDate
, DayN
, WeekN
, YearN
, DayOfMonthN
, [Start Date]
, [End Date]
, [Inspection Number]
, [Dates] = STUFF((
SELECT ',' + CONVERT(VARCHAR(10), C.CalDate,105)
FROM #Calendar AS C
WHERE C.CalDate BETWEEN IR.[Start Date] AND IR.[End Date]
FOR XML PATH('')
), 1, 1, '')
FROM #Calendar AS dateInfo
LEFT JOIN [Inspection Records] AS IR
ON IR.[Start Date] = dateInfo.CalendarDate
This will put all your dates into a variable named #csv.
I'm sure you'll be able to modify to suit your needs.......
DECLARE #csv nVarchar(max)
SELECT #csv = COALESCE(#csv + ', ', '') + CONVERT(Nvarchar(20), yourDateColumn)
FROM yourDateTable
I'm having some trouble with syntax.
First, I'd like to convert a date from this format:
2014-12-18 21:49:54.047
To this format:
20141218
I can do this just fine using this select statement:
SELECT F253 = CONVERT (VARCHAR (20), F253, 112)
FROM SAL_HDR
My problem is with the syntax. How do I put that select statement inside of a select statement with a bunch of other lines? I can't seem to make it work right. I have commented out the line in question. How do I write that line into the larger select statement?
SELECT
SAL_HDR.F253 AS [Transaction Date],
/*F253 = CONVERT (VARCHAR (20), F253, 112)*/
SAL_HDR.F1036 AS [Transaction Time],
SAL_HDR.F1032 AS [Transaction #],
FROM SAL_HDR
Just add it in as an expression:
SELECT CONVERT(VARCHAR(20), SAL_HDR.F253, 112) AS [Transaction Date],
SAL_HDR.F1036 AS [Transaction Time],
SAL_HDR.F1032 AS [Transaction #]
FROM SAL_HDR;
Alternatively, you can use the syntax:
SELECT [Transaction Date] = CONVERT(VARCHAR(20), SAL_HDR.F253, 112),
[Transaction Time] = SAL_HDR.F1036,
[Transaction #] = SAL_HDR.F1032
FROM SAL_HDR;
I personally prefer the first version, because I find that the second is too close to variable assignment.