Dynamic table creation SQLSever - sql-server

I have several tables in SQL sever worth of Employee data including ID's and clock in times. I need to create a report to show clocking times for each day for each employee. i have done this with the below code. However as the clock ins are only recorded if there is an entry i need to show working days where there are no records for a clock in for employees. I've thought about making a table of working days in 2019/2020 including data each employee on each day and using this to join however the table would need continual updating when somebody new starts.
Is there any way the table can update itself with employee numbers and copy working days?
Any help would be appreciated
Thanks
select distinct cast(a.DET_NUMBER as varchar) as 'Frontier ID',
e.CDN_CARD_ID,
CONCAT (a.DET_G1_NAME1, ' ', a.DET_SURNAME) as 'Name',
c.POS_TITLE as 'Position',
c.POS_L3_CD as 'Department',
c.POS_L4_CD as 'Department 2',
cast(a.DET_DATE_JND as date) as 'Start Date',
cast(b.TER_DATE as date) as 'Leaving Date',
CONCAT (d.DET_G1_NAME1, ' ', d.DET_SURNAME) as 'Team Manager',
f.CLO_DATE2,
min(CLO_TIME2) over (partition by f.CLO_DATE2, e.CDN_CARD_ID) as earliest_time,
max(CLO_TIME2) over (partition by f.CLO_DATE2, e.CDN_CARD_ID) as latiest_time
from EMDET a
left outer join EMTER b on a.DET_NUMBER = b.DET_NUMBER
left outer join EMPOS c on a.DET_NUMBER = c.DET_NUMBER
left outer join EMDET d on c.POS_MANEMPNO = d.DET_NUMBER
left outer join TACDN e on a.DET_NUMBER = e.DET_NUMBER
left outer join TACLO f on e.CDN_CARD_ID = f.CLO_CARD_NO
Where (b.TER_DATE is null or c.POS_END>=GETDATE())
and c.POS_TITLE is not null
and (c.POS_END<=Cast('1992-01-01' as datetime) or c.POS_END>=GETDATE())
and f.CLO_DATE >='2019-01-01'
order by [Team Manager] asc,
e.CDN_CARD_ID asc,
f.CLO_DATE2 asc

You can generate a calendar with a CTE
DECLARE #Start DATE = '2018-1-1', #End DATE = GETDATE()
;WITH
dates AS
(
SELECT thedate = #Start
UNION ALL
SELECT dateadd(day,1,dates.thedate)
FROM dates
WHERE dateadd(day,1,dates.thedate) <= #End
)
SELECT *
FROM dates c
OPTION (maxrecursion 0);
Then filter to exclude non-working days (weekens: direct in yourquery, holidays, vacations, permits, etc from other table)
Left join with your actual query

Related

Display of online users on the system

I don't know exactly where I'm wrong, but I need a list of all the workers who are currently at work (for the current day), this is my sql query:
SELECT
zp.ID,
zp.USER_ID,
zp.Arrive,
zp.Deppart,
zp.DATUM
FROM time_recording as zp
INNER JOIN personal AS a on zp.USER_ID, = zp.USER_ID,
WHERE zp.Arrive IS NOT NULL
AND zp.Deppart IS NULL
AND zp.DATUM = convert(date, getdate())
ORDER BY zp.ID DESC
this is what the data looks like with my query:
For me the question is, how can I correct my query so that I only get the last Arrive time for the current day for each user?
In this case to get only these values:
Try this below script using ROW_NUMBER as below-
SELECT * FROM
(
SELECT zp.ID, zp.USER_ID, zp.Arrive, zp.Deppart, zp.DATUM,
ROW_NMBER() OVER(PARTITION BY zp.User_id ORDER BY zp.Arrive DESC) RN
FROM time_recording as zp
INNER JOIN personal AS a
on zp.USER_ID = zp.USER_ID
-- You need to adjust above join relation as both goes to same table
-- In addition, as you are selecting nothing from table personal, you can drop the total JOIN part
WHERE zp.Arrive IS NOT NULL
AND zp.Deppart IS NULL
AND zp.DATUM = convert(date, getdate())
)A
WHERE RN =1
you can try this:
SELECT DISTINCT
USER_ID,
LAR.LastArrive
FROM time_recording as tr
CROSS APPLY (
SELECT
MAX(Arrive) as LastArrive
FROM time_recording as ta
WHERE
tr.USER_ID = ta.USER_ID AND
ta.Arrive IS NOT NULL
) as LAR

How to use the current select column value in a column sub select in SQL

I have a query that for each row, adds a comma seperated string to one column using a sub query. So for example, a work order may be attached to many parts. I do my regular select, but use the SQL function 'STUFF' to build the 'Parts column. That way in the results, the arts column has multiple entries. So i do i do the sub query for the column i use 'STUFF" on to get all parts using the main column id of the base query? This is a little weird for me to explain but this snippet will help you understand what i am trying to accomplish:
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
SET FMTONLY OFF;
IF OBJECT_ID('tempdb..#TEMP_KikusuiRpt') IS NOT NULL DROP TABLE #TEMP_KikusuiRpt
-- Get the current date to work on if they do not send in date params. Meaning it is automated run --
-- if hey do send in date ranges, then it is manual run
IF NULLIF(#StartDate, '') IS NULL
BEGIN
-- Set start date param to the first day of the current month
SET #StartDate = DATEADD(mm, DATEDIFF(mm,0,GETDATE()), 0)
END
IF NULLIF(#EndDate, '') IS NULL
BEGIN
-- Set end day to the last day what ever that may be of the current month.
SET #EndDate = DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE())+1,0))
END
SELECT
manufacturer.mfrname AS Manufacturer,
model.modelnumber AS BaseModelNumber,
control.controlserialnumber AS Serial,
Customer.CustCompany,
Control.ControlDateAdded as Received,
Control.ControlCalDate as 'Completed (Cal Date)',
WorkOrder.WorkOrderID as woid,
Receiver.ReceiverID,
WorkOrderComments.CommentRcvr as 'Receiver Comments',
WorkOrderCOmments.CommentRpt as 'Report Comments',
ISNULL(STUFF((SELECT ', ' + PartID
FROM WorkOrderPart WOP
INNER JOIN WorkORder WO ON WOP.WorkOrderID = WO.WorkOrderID
INNER JOIN Model ON Model.ModelID = WO.ModelID
WHERE WO.MfrCode IN (SELECT MfrCode FROM Manufacturer where MfrName LIKE '%Kikusui%')
--
-- Right here i need somehow to do this
--
-- the workorder on the stuff query needs to be attached to the base select work order row instance, or else i get all parts in each row not just for the work order
where wo.WorkOrderID = WOID
FOR XML PATH('')
), 1, 1, ''), 'NA') AS Parts
INTO #TEMP_KikusuiRpt
FROM WorkOrder
INNER JOIN Control ON WorkOrder.ControlNumber = Control.ControlNumber
INNER JOIN model ON control.modelid = model.modelid
INNER JOIN manufacturer on model.mfrcode = manufacturer.mfrcode
INNER JOIN WorkOrderComments ON WorkOrderComments.WorkOrderID = WorkOrder.WorkOrderID
INNER JOIN Receiver ON Receiver.ReceiverID = WorkOrder.ReceiverID
INNER JOIN Customer ON Customer.CustID = WorkOrder.CustID
WHERE Manufacturer.MfrName LIKE '%Kikusui%'
AND #StartDate > WorkOrder.DateReceived
AND #EndDate < WorkOrder.DateCompleted
SELECT * FROM #TEMP_KikusuiRpt
DROP TABLE #TEMP_KikusuiRpt
So hopefully i have explained this clearly enough. Is there a way to handle this? The reason being that my Parts column is populated, but not filtered enough to the model that is returned.
You just need to alias your outer and inner model table references. Here's what the main select would look like:
SELECT
manufacturer.mfrname AS Manufacturer,
m1.modelnumber AS BaseModelNumber,
control.controlserialnumber AS Serial,
Customer.CustCompany,
Control.ControlDateAdded as Received,
Control.ControlCalDate as 'Completed (Cal Date)',
WorkOrder.WorkOrderID as woid,
Receiver.ReceiverID,
WorkOrderComments.CommentRcvr as 'Receiver Comments',
WorkOrderCOmments.CommentRpt as 'Report Comments',
ISNULL(STUFF((SELECT ', ' + PartID
FROM WorkOrderPart WOP
INNER JOIN WorkORder WO ON WOP.WorkOrderID = WO.WorkOrderID
INNER JOIN Model m2 ON m2.ModelID = WO.ModelID
WHERE WO.MfrCode IN (SELECT MfrCode FROM Manufacturer where MfrName LIKE '%Kikusui%')
AND m1.modelnumber = m2.modelnumber
FOR XML PATH('')
), 1, 1, ''), 'NA') AS Parts
INTO #TEMP_KikusuiRpt
FROM WorkOrder
INNER JOIN Control ON WorkOrder.ControlNumber = Control.ControlNumber
INNER JOIN model m1 ON control.modelid = m1.modelid
INNER JOIN manufacturer on m1.mfrcode = manufacturer.mfrcode
INNER JOIN WorkOrderComments ON WorkOrderComments.WorkOrderID = WorkOrder.WorkOrderID
INNER JOIN Receiver ON Receiver.ReceiverID = WorkOrder.ReceiverID
INNER JOIN Customer ON Customer.CustID = WorkOrder.CustID
WHERE Manufacturer.MfrName LIKE '%Kikusui%'
AND #StartDate > WorkOrder.DateReceived
AND #EndDate < WorkOrder.DateCompleted

How to get the transaction data with Date from First transaction date and Address from latest transaction Date if updated?

I am trying to rearrange the data with Date as First transaction/Shopping date and address from latest transaction. The Data consists of transaction of a single customer on various dates. Please help.
The Desired Out should be like:
Due to lack of table structure etc., here some "dummy" code. The idea is to first evaluate min and max date for each customer and then perform a join between the corresponding records:
WITH cte AS(
SELECT [Customer Code_Transaction]) AS CustomerCode
,min([Invoice Date_Transaction]) AS MinDate
,max([Invoice Date_Transaction]) AS MaxDate
FROM [yourtable...]
GROUP BY [Customer Code_Transaction]
)
SELECT t1.[Invoice Date_Transaction]
,t1.[Customer Code_Transaction]
,t1.[Customer Name_Transaction]
,t2.[Address_CustReport]
FROM [yourtable...] AS t1
JOIN cte AS c ON c.MinDate = t1.[Invoice Date_Transaction] AND c.CustomerCode = t1.[Customer Code_Transaction]
JOIN [yourtable...] AS t2 ON t2.[Customer Code_Transaction] = c.[Customer Code_Transaction] AND t2.[Invoice Date_Transaction] = c.MaxDate

Running 3-Tier T-SQL Query for Report

First question here so please excuse any mistakes...
I am trying to write a SQL Query for an SSRS report and I am totally confused when it comes to my joins.
Background: I have 3 tables that are relevant
Publishers - This is essentially a list of people
Publisher Reports - This is a list of records (related to the Publisher table) that details the work they have completed in a month period.
Report Months - This is a list of records (related to the Publisher Reports table) that relates to a specific month and year. On these records they have an indicator to show whether they relate to the previous six month period.
What i am trying to do is get a list of Publishers who have not submitted a publisher report that is related to a Report Month record within the last 6 months. My desired output is a list of Publishers in on column with the Report Month(s) that they are missing in the next column.
I am really struggling how to do it... I had thought of it as a three step process...
--STEP 1 - Get list of report months that are included in the last 6 months
WITH ACTIVE6MREPM AS
(
SELECT r.jajw_name,
r.jajw_CalendarDate
FROM jajw_reportmonthBase r
WHERE r.jajw_IncludedIn6MonthReport = '1'
),
--STEP 2 - Get list of all publishers
ACTIVEPUBS AS
(
SELECT c.FullName,
c.ContactId
FROM ContactBase c
WHERE c.statecode = '0'
AND c.jajw_CongregationAssignment != 640840001
AND c.jajw_CongregationAssignment != 640840006
AND c.jajw_CongregationAssignment != 640840005
--AND q.jajw_FieldServiceGroups = (#Field_Service_Group)
),
--STEP 3 - Get List of Publisher Reports for the selected Report Months
RELEVANTREPORTS AS
(
SELECT r.jajw_reportId AS Publisher_Report_GUID,
r.jajw_PublisherId AS Publisher_GUID,
r.jajw_ReportMonthId AS ReportMonth_GUID,
m.jajw_name AS ReportMonth_Name
FROM jajw_reportBase r
INNER JOIN jajw_reportmonthBase m ON r.jajw_ReportMonthId = m.jajw_reportmonthId
WHERE r.jajw_ReportPeriod6Month = '1'
ORDER BY m.jajw_CalendarDate
After these three, I want to create my list as described above and this is the bit that has me stumped! Any help would be greatly appreciated!
Thanks!
I think you can shorten your code a lot... here's a shot at it without having test data... be sure to read the comments and add in the join condition and check the where clause.
with cte as(
SELECT r.jajw_reportId AS Publisher_Report_GUID,
r.jajw_PublisherId AS Publisher_GUID,
r.jajw_ReportMonthId AS ReportMonth_GUID,
m.jajw_name AS ReportMonth_Name,
c.FullName,
c.ContactId
FROM jajw_reportBase r
INNER JOIN jajw_reportmonthBase m ON
r.jajw_ReportMonthId = m.jajw_reportmonthId
INNER JOIN ContactBase c on --what ever condition is appropiate
WHERE r.jajw_ReportPeriod6Month = '1'
and m.jajw_IncludedIn6MonthReport = '1' --maybe put this here, or does the above do the same thing?
ORDER BY m.jajw_CalendarDate)
select
p2.FullName,
p2.ReportMonth_Name
from cte p
right join(select distinct
ReportMonth_Name, FullName
from ContactBase
left join jajw_reportmonthBase on 1=1) p2 on p2.FullName = p.FullName and p2.ReportMonth_Name = p.ReportMonth_Name
where
ContactId in (select ContactId from cte group by ContactId having count(distinct ReportMonth_GUID) < 6)
and p.FullName is null
Here is an example using test data.
declare #pub table (pubname varchar(56), ReportMonthName varchar(16))
insert into #pub (pubname,ReportMonthName) values
('a','Jan'),
('a','Feb'),
('a','Mar'),
('a','Apr'),
--publisher a is missing May and Jun
('b','Jan'),
('b','Feb'),
('b','Mar'),
('b','Jun')
--publisher b is missing Apr and May
declare #dt table (ReportMonthName varchar(16))
insert into #dt (ReportMonthName) values
('Jan'),
('Feb'),
('Mar'),
('Apr'),
('May'),
('Jun')
select
p2.pubname
,p2.ReportMonthName
from #pub p
right join(
select distinct
p.pubname
,d.ReportMonthName
from #pub p
left join #dt d on 1=1)p2 on p2.pubname = p.pubname and p2.ReportMonthName = p.ReportMonthName where p.pubname is null

SQL Server T-SQL: Get a records set based on a priority value, startdate and enddate

I am working on an time attendance system. I have to following tables:
Schedule: Contains a Name nvarchar field and a Start and End DateTime fields.
Policy: Contains Start and End DateTime fields too.
PolicySchedule (Cross Table): Contains a Priority int field beside the foreign keys.
End datetime fields are nullable which indicates open periods.
The schedule of the greatest priority will be applied and activated within its time and the policy time.
I need to get a list of the applied schedules within each policy and their activation periods start and end time knowing that shedules may be intersected. Policies are not related here ..
Example:
Schedule_____________Start_________________________End
Schedule1____________01/01/2011 00:00______________04/01/2011 00:00
Schedule2____________04/01/2011 00:00______________11/01/2011 14:00
Schedule3____________11/01/2011 14:00______________02/15/2012 00:00
Schedule2____________02/15/2012 00:00______________01/01/2013 00:00
What is the most efficient way to get the requested result ?
If you have lots of policies and schedules (separately) but few schedules per policy, the most straightforward way would be quite efficient:
WITH dates (policyId, changeDate) AS
(
SELECT policyId, changeDate,
ROW_NUMBER() OVER (PARTITION BY policyId ORDER BY changeDate) AS rn
FROM (
SELECT policyId, startDate AS changeDate
FROM policySchedule ps
JOIN schedule s
ON s.id = ps.scheduleId
UNION
SELECT policyId, endDate AS changeDate
FROM policySchedule ps
JOIN schedule s
ON s.id = ps.scheduleId
) q
),
ranges (startDate, endDate)AS
(
SELECT d1.policyId,
d1.changeDate,
d2.changeDate
FROM dates d1
JOIN dates d2
ON d2.policyId = d1.policyId
AND d2.rn = d1.rn + 1
)
SELECT *
FROM policy p
JOIN ranges r
ON r.policyId = p.id
CROSS APPLY
(
SELECT TOP 1 s.*
FROM policySchedules ps
JOIN schedule s
ON ps.policyId = p.id
AND s.id = ps.scheduleId
WHERE ps.startDate BETWEEN r.startDate AND r.endDate
AND ps.endDate BETWEEN r.startDate AND r.endDate
ORDER BY
ps.Priority DESC
)
Assuming you're using SQL Server 2005 or later, you can use an outer apply to look up the policy with the highest priority:
select *
from Schedule s
outer apply
(
select top 1 *
from PolicySchedule ps
join Policy p
on p.id = ps.policyid
where s.StartTime <= p.EndTime
and p.StartTime <= s.EndTime
order by
ps.priority desc
) pol
If there are time periods that have to overlap, you can add a where clause in the outer apply.

Resources