i want to get data through fromDate & toDate on employe code - sql

here is my stored procedure...this stored procedure showing result for fromdate and toate on employee code,an aggregate function for differentiate checkIn and checkout...
it shows data for checkout time only for one date,the problem is ,I need this for multiple days...
If any one know what is the problem kindly share your experience with me, and point my mistakes in query...
I shall be thankful
here is the tables script
CREATE TABLE [dbo].[ras_AttRecord](
[ID] [int] IDENTITY(1,1) NOT NULL,
[DN] [smallint] NULL,
[DIN] [bigint] NOT NULL,
[Clock] [datetime] NOT NULL,
[VerifyMode] [tinyint] NULL,
[AttTypeId] [char](3) NOT NULL,
[CollectDate] [datetime] NOT NULL,
[LastUpdatedUID] [int] NULL,
[LastUpdatedDate] [datetime] NULL,
[Remark] [nvarchar](64) NULL
)
CREATE TABLE [dbo].[ras_Users](
[UID] [int] NOT NULL,
[DIN] [bigint] NOT NULL,
[PIN] [varchar](32) NOT NULL,
[UserName] [nvarchar](64) NULL,
[Sex] [char](1) NOT NULL,
[Password] [nvarchar](32) NULL,
[PasswordQuestion] [nvarchar](64) NULL,
[PasswordAnswer] [nvarchar](32) NULL,
[IsApproved] [bit] NOT NULL,
[IsLockedOut] [bit] NOT NULL,
[CreateDate] [datetime] NULL,
[LastLoginDate] [datetime] NULL,
[DeptId] [varchar](64) NOT NULL,
[AttId] [char](4) NULL,
[RuleId] [char](4) NULL,
[WeekendId] [char](4) NULL,
[LastUpdatedUID] [int] NULL,
[LastUpdatedDate] [datetime] NOT NULL,
[Comment] [nvarchar](128) NULL
)
I'm using this stored procedure
ALTER PROCEDURE [dbo].[GetLateComersmonthly]
#FromDate DATE='05/22/2017',
#ToDate DATE='06/06/2017',
#Code varchar(6) ='3155'
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
IF #Code = '0'
SET #Code = null
-- Insert statements for procedure here
select
T1.UserName,
T1.DIN as [DIN],
min(T1.Date) as [Date],
min(T1.Time) as [Time],
CASE
WHEN max(T2.Time) = max(T1.Time) THEN ''
ELSE max(T2.Time) end as [Timee], min(T1.Day) as [Day],
CASE
WHEN concat(CONVERT(varchar,DATEDIFF(MINUTE,min(T1.Time),max(t2.Time)),108)/60,
':',
CONVERT(varchar,DATEDIFF(MINUTE,min(T1.Time),max(t2.Time))%60,108)) = '0:0'
THEN 'No Check Out'
ELSE concat(CONVERT(varchar,DATEDIFF(MINUTE,min(T1.Time),max(t2.Time)),108)/60,
':',
CONVERT(varchar,DATEDIFF(MINUTE,min(T1.Time),max(t2.Time))%60,108))
END AS hrs
from
(SELECT
UserName ,
ru.DIN,
CONVERT(varchar, Att.Clock, 101) AS Date,
CONVERT(varchar, Att.Clock, 108) AS Time,
att.VerifyMode as Mode, DATENAME(dw, Att.Clock) AS Day
FROM
ras_Users as ru
inner join ras_AttRecord as att ON ru.DIN = att.Din
where CONVERT(DATE,Clock) >= #FromDate
and CONVERT(DATE,Clock)<=#ToDate
and att.DIN = COALESCE (#Code, att.DIN)
and att.VerifyMode = 15
) as T1
left join
(SELECT
ru.DIN,
max(CONVERT(varchar, Att.Clock, 108)) AS Time
FROM
ras_Users as ru
inner join ras_AttRecord as att ON ru.DIN = att.Din
where CONVERT(DATE,Clock) >= #FromDate
and CONVERT(DATE,Clock)<=#ToDate
and att.DIN = COALESCE (#Code, att.din)
group by ru.DIN, att.Clock
) as T2 on T1.DIN = T2.DIN --and DATEDIFF(MINUTE,T1.Time,t2.Time)/60 < 9
group by
T1.Username,
T1.din,
T1.Day
-- having CONVERT(varchar, min(T1.Time), 108) > '09:30:00'
order by T1.din
END
its shows the following result
Current Record displaying
Userid Date CheckIn CheckOut Day total hours
3155 05/26/2017 09:15:10 17:15:00 Friday 8:0
3155 05/29/2017 09:08:36 17:15:00 Monday 8:7
3155 05/25/2017 09:34:28 17:15:00 Thursday 7:41
3155 05/30/2017 09:15:12 17:15:00 Tuesday 8:0
3155 05/31/2017 09:27:37 17:15:00 Wednesday 7:48
and I need the following result
Expected Result
Userid Date CheckIn CheckOut day total hours
3155 05/26/2017 09:15:10 17:00:00 Friday 8:0
3155 05/29/2017 09:08:36 17:05:00 Monday 8:7
3155 05/25/2017 09:34:28 17:30:00 Thursday 7:41
3155 05/30/2017 09:15:12 17:18:00 Tuesday 8:0
3155 05/31/2017 09:27:37 17:10:00 Wednesday 7:48

Related

Create interval for recording

I have a table of schedule templates.
CREATE TABLE [dbo].[Template]
(
[ID] [uniqueidentifier] NOT NULL,
[Name] [nvarchar](50) NULL,
[Interval] [nvarchar](50) NULL,-- reception interval in minutes
[Activate] [bit] NOT NULL,-- is the template active or not
) ON [PRIMARY]
Therefore, only one template is active at any time, and for each template there is an n-th number of schedule intervals
CREATE TABLE [dbo].[Schedule]
(
[ID] [uniqueidentifier] NOT NULL,
[TemplateID] [uniqueidentifier] NULL,
[StartTime] [nvarchar](50) NULL, --start of available recording time
[EndTime] [nvarchar](50) NULL,--end of available recording time
[Monday] [bit] NULL,-- True or false whether the entry is available on Monday
[Tuesday] [bit] NULL,
[Wednesday] [bit] NULL,
[Thursday] [bit] NULL,
[Friday] [bit] NULL,
[Saturday] [bit] NULL,
[Sunday] [bit] NULL
) ON [PRIMARY]
I also have a table in which records and occupied time are already stored:
CREATE TABLE [dbo].[EventRecord]
(
[ID] [uniqueidentifier] NOT NULL,
[PeopleID] [uniqueidentifier] NULL,
[TemplateID] [uniqueidentifier] NULL,
[DateTime] [datetime] NULL,-- date and time of an already created entry
[Interval] [nvarchar](max) NULL,
[CheckOut] [bit] NULL,
[Details] [nvarchar](max) NULL
) ON [PRIMARY]
I need to write a stored procedure (query) that would return the available time for recording (if possible, in one query) given:
Reception interval
Already taken time by other records
Days of the week.
I can build the intervals of one Schedule, but how can I do this for all Schedules of one template and exclude the time for which I signed up.
DECLARE #intervalMinutes int = 10
DECLARE #myDates TABLE
(
startTime datetime,
endTime datetime
)
DECLARE #startTime DATETIME = '2016-07-10 08:00'
DECLARE #endTime DATETIME = '2016-07-10 22:00'
;WITH CTE AS
(
SELECT #startTime st
UNION ALL
SELECT DATEADD (MINUTE, #intervalMinutes, st) st
FROM cte
WHERE DATEADD (MINUTE, #intervalMinutes, st) < #endTime
)
SELECT st, DATEADD (MINUTE, #intervalMinutes, st)
FROM cte

Add two datetime columns and divide result by 2 in SQL Server

If actual start date != ‘’ and complete date != '' calculate the mid trim date = (actual start date + complete date)/2
My table
CREATE TABLE [dbo].[AR_Placebook]
(
[Region] nvarchar(255) NULL,
[Network Area Description] [nvarchar](255) NULL,
[Substation] [nvarchar](255) NULL,
[Circuit] [nvarchar](255) NULL,
[Original (O) or Added Circuit (A)] [nvarchar](255) NULL,
[OC] [nvarchar](255) NULL,
[Line Miles] [float] NULL,
[Line Miles Complete] [float] NULL,
[Percent Complete] [float] NULL,
[Contractor] [float] NULL,
[Final Circuit Performance Audit] [nvarchar](255) NULL,
[Should Be Billed] [float] NULL,
[Invoiced to Date] [float] NULL,
[Gap in Billing Difference] [float] NULL,
[VCKT Number] [nvarchar](255) NULL,
[Bid Cost ] [float] NULL,
[Bid Cost per Line Mile] [float] NULL,
[Predictive Dialer Start Date] [nvarchar](255) NULL,
[ESTIMATED TRIM QUARTER] [nvarchar](255) NULL,
[Actual Start Date] [datetime] NULL,
[Complete Date] [datetime] NULL,
[MidTrimDate] [datetime] NULL
)
I have tried this
DECLARE #StartTime DATETIME
,#EndTime DATETIME
DECLARE #TotalWorkingHours varchar(50)
Declare #HalfDayCalculate varchar(50)
Declare #DivdeWorkingHours int
set #DivdeWorkingHours=2
SELECT #TotalWorkingHours = CONVERT(VARCHAR(8), DATEADD(SECOND,DATEDIFF(SECOND,#StartTime, #EndTime),0), 108)
from AR_Placebook
where #StartTime=[Actual Start Date] and
#EndTime =[Complete Date] and
[Actual Start Date]!='' and
[Complete Date]!=''
set #HalfDayCalculate = convert(TIME(0), dateadd(second, datediff(second, 0, #TotalWorkingHours) / #DivdeWorkingHours, 0),108)
select #HalfDayCalculate as MidTrimDate
You can go with different approach - calculate the date difference between the two dates using DATEDIFF (https://learn.microsoft.com/en-us/sql/t-sql/functions/datediff-transact-sql?view=sql-server-ver15), divide the result of the DATEDIFF by 2 and subtract this value from the complete date.
Please find below the answer as per your requirement.
SELECT [start date],DATEADD(DAY,day_difference,[start date]) AS [mid_date],[complete date],day_difference
FROM
(
SELECT '2020-03-01' AS[start date], '2020-03-20' AS[complete date],DATEDIFF(DAY,'2020-03-01' ,'2020-03-20')/2 as day_difference
)A
Also, find below snap.
enter image description here
If actual start date != ‘’ and complete date != '' calculate the mid trim date = (actual start date + complete date)/2
I think you are looking for. For the middle day:
select dateadd(day,
datediff(day, start_date, complete_date) / 2,
start_date
)
If there is a time component, use a smaller time unit:
select dateadd(second,
datediff(second, start_date, complete_date) / 2,
start_date
)

t-sql end of month insert

I have created two database tables named TSALESFACT and DimDate. TSALESFACT table contains the monthly sales target values. And DimTime contains the date values which begins from 01/01/2005.
CREATE TABLE [dbo].[TSalesFact](
[DateID] [smalldatetime] NULL,
[YearID] [int] NOT NULL,
[MonthID] [int] NOT NULL,
[SeasonID] [char](10) NOT NULL,
[DepartmentID] [char](10) NOT NULL,
[SalesAmount] [int] NOT NULL
)
CREATE TABLE [dbo].[dim_Date](
[ID] [int] NOT NULL,
[Date] [datetime] NOT NULL,
[Day] [char](2) NOT NULL,
[DaySuffix] [varchar](4) NOT NULL,
[DayOfWeek] [varchar](9) NOT NULL,
[DOWInMonth] [tinyint] NOT NULL,
[DayOfYear] [int] NOT NULL,
[WeekOfYear] [tinyint] NOT NULL,
[WeekOfMonth] [tinyint] NOT NULL,
[Month] [char](2) NOT NULL,
[MonthName] [varchar](9) NOT NULL,
[Quarter] [tinyint] NOT NULL,
[QuarterName] [varchar](6) NOT NULL,
[Year] [char](4) NOT NULL,
[StandardDate] [varchar](10) NULL,
[HolidayText] [varchar](50) NULL)
I would like to INSERT these sales target values into a new table named DailySalesTargets. But, the main purpose of this operation is writing the target sales to the each of end of month date. All of the date values for the relevant month will be zero. My desired resultset for this operation is like below:
How can I achieve this? Any idea?
I think this is what you are trying to do.
insert into [DailySalesTargets]([DateID],[YearID],[MonthID],
[SeasonID],[DepartmentID],[SalesAmount])
select d.[Date],d.[Year],d.[Month]
,dptSeason.[SeasonID],dptSeason.[DepartmentID]
,case when EOMONTH(d.[Date])=s.[DateID] then s.[SalesAmount] else 0 end as [SalesAmount]
from [dbo].[dim_Date] d
cross join (select distinct [DepartmentID],[SeasonID] from [dbo].[TSalesFact]) dptSeason
left join [dbo].[TSalesFact] s on d.[Date] = s.[DateID]
and s.[DepartmentID]=dptSeason.[DepartmentID]
and s.[SeasonID]=dptSeason.[SeasonID]

Can I make this stored procedure faster

I have the stored procedure below. This stored procedure runs in 3-4 seconds even on my developer computer but on the server it takes 15-20 seconds. I tried to change some of subqueries to cross apply and some to outer apply. But it caused to take more longer time.
#startDate datetime ,
#endDate datetime ,
#customerId int
;WITH t1(Plate,UsedFuelTypeUID,RemainingBefore,DateRangeTotal,DateRangeTransactionsTotal,RemaininCurrent) AS
(
select
v.Plate, v.UsedFuelTypeUID,
isnull((select isnull( sum(vls1.FT_TotalLimit),0)
from VehicleChildLog vls1
where vls1.VehicleChildId =v.VehicleID and vls1.UpdateDate < #startDate
),0)-
isnull((select isnull( sum(t1.Liter),0) from Transactions t1
where t1.VehicleChildID=v.VehicleID and t1.SaleDate <#startDate
),0)as RemainingBefore,
sum(vl.FT_TotalLimit) DateRangeTotal,
isnull((select isnull( sum(t1.Liter),0) from Transactions t1
where t1.VehicleChildID=v.VehicleID and t1.SaleDate between #startDate and #endDate
),0) as DateRangeTransactionsTotal,
(v.FT_TotalLimit - v.FT_UsedTotalLimit) as RemainingCurrent
from VehicleChildLog vl
inner join VehiclesChild v on vl.VehicleChildId = v.VehicleID
where vl.CustomerChildID = #customerId and vl.UpdateDate between #startDate and #endDate
group by
v.VehicleID, v.Plate, v.UsedFuelTypeUID
,v.FT_TotalLimit - v.FT_UsedTotalLimit
)
select *, t1.RemainingBefore+t1.DateRangeTotal-t1.DateRangeTransactionsTotal as RemainingAfter from t1 ;
Table structure is below
[Transactions]
(
[TransactionID] [int] IDENTITY(1,1) NOT FOR REPLICATION NOT NULL,
[SaleDate] [datetime] NULL,
[Liter] [float] NULL,
[VehicleChildID] [int] NULL
...
)
[VehiclesChild]
(
[VehicleID] [int] IDENTITY(1,1) NOT NULL,
[CustomerChildID] [int] NULL,
[Plate] [varchar](16) NULL,
[UsedFuelTypeUID] [int] NULL,
[FT_TotalLimit] [float] NULL,
[FT_UsedTotalLimit] [float] NULL
...
)
[VehicleChildLog]
(
[VehiclesChildLogId] [int] IDENTITY(1,1) NOT NULL,
[VehicleChildId] [int] NOT NULL,
[CustomerChildId] [int] NOT NULL,
[FT_TotalLimit] [float] NULL,
[FT_UsedTotalLimit] [float] NULL,
[UpdateDate] [datetime] NULL
...
)

SQL select all records only if the sum is greater than 0

I have the following SQL;
ALTER PROCEDURE [dbo].[MyReport]
#startdate datetime,
#enddate datetime
AS
/* Return the event plan (coming events) for a specific volunteer */
declare #sd datetime
declare #ed datetime
/* Ensure that the start and end dates covert whole days */
set #sd = convert(varchar(10),#startdate,120) + ' 00:00:00'
set #ed = convert(varchar(10),#enddate,120) + ' 23:59:59'
SELECT
E.EventID, E.EventDate, E.StartTime, E.StartLocation, E.EndTime,
E.EndLocation, E.Charged, E.Actual,E.ChargeRate, E.Cost,
E.Persons, E.Reason,
C.ClientID, C.Address1, C.Address2,
C.Town, C.County, C.Postcode,
C.InvoiceName, C.InvoiceAddress1, C.InvoiceAddress2,
C.InvoiceTown, C.InvoiceCounty, C.InvoicePostCode,
ISNULL(C.Surname, '') + ', ' + ISNULL(C.Forename, '') AS ClientSurnameForename
FROM
vEvents E
INNER JOIN
vClients C ON E.ClientID = C.ClientID
WHERE
(E.EventDate BETWEEN #sd AND #ed)
AND E.SchemeID = 4
ORDER BY
c.Surname, c.Forename, E.EventDate, E.StartTime, E.EndTime
I need to sum the column E.Charged to check see if the amount for the client is greater than 0 before returning the recordset. I have tried the following:
ALTER PROCEDURE [dbo].[MyReport]
#startdate datetime,
#enddate datetime
AS
/* Return the event plan (coming events) for a specific volunteer */
declare #sd datetime
declare #ed datetime
/* Ensure that the start and end dates covert whole days */
set #sd = convert(varchar(10),#startdate,120) + ' 00:00:00'
set #ed = convert(varchar(10),#enddate,120) + ' 23:59:59'
SELECT
E.EventID, E.EventDate, E.StartTime, E.StartLocation, E.EndTime,
E.EndLocation, E.Charged, E.Actual,E.ChargeRate, E.Cost,
E.Persons, E.Reason,
C.ClientID, C.Address1, C.Address2, C.Town, C.County, C.Postcode,
C.InvoiceName, C.InvoiceAddress1, C.InvoiceAddress2, C.InvoiceTown,
C.InvoiceCounty, C.InvoicePostCode,
ISNULL(C.Surname, '') + ', ' + ISNULL(C.Forename, '') AS ClientSurnameForename
FROM
vEvents E
INNER JOIN
vClients C ON E.ClientID = C.ClientID
WHERE
vEvents.ClientID IN (SELECT vEvents.Charged
FROM vEvents
GROUP BY vEvents.ClientID, vEvents.charged
HAVING SUM(vEvents.Charged) > 0)
AND (E.EventDate BETWEEN #sd AND #ed)
AND E.SchemeID = 4
ORDER BY
c.Surname, c.Forename, E.EventDate, E.StartTime, E.EndTime
But I keep getting 'the multipart identifier could not be bound'. TIA Andrew
Table Structure
[vEvents](
[EventID] [int] IDENTITY(1,1) NOT NULL,
[ClientID] [int] NOT NULL,
[ChargeID] [int] NOT NULL,
[EventDate] [datetime] NULL,
[StartTime] [datetime] NULL,
[StartLocation] [nvarchar](50) NULL,
[EndTime] [datetime] NULL,
[EndLocation] [nvarchar](50) NULL,
[Reason] [nvarchar](50) NULL,
[Charged] [decimal](6, 2) NOT NULL,
[Actual] [decimal](6, 2) NOT NULL,
[Additional] [decimal](6, 2) NOT NULL,
[Done] [bit] NOT NULL,
[Verifier] [nvarchar](50) NULL,
[ChargeRate] [decimal](6, 4) NULL,
[TeamID] [int] NOT NULL,
[Combined] [bit] NOT NULL,
Its an edit list but contains the most relevant
The Client Table
[vClients](
[ClientID] [int] IDENTITY(1,1) NOT NULL,
[ManagerID] [int] NOT NULL,
[RegularID] [int] NOT NULL,
[Forename] [nvarchar](50) NULL,
[Surname] [nvarchar](50) NULL,
[Address1] [nvarchar](50) NULL,
[Address2] [nvarchar](50) NULL,
[Town] [nvarchar](50) NULL,
[County] [nvarchar](50) NULL,
[PostCode] [nvarchar](10) NULL,
[Telephone] [nvarchar](30) NULL,
[Comments] [ntext] NULL,
[ReviewDate] [datetime] NULL,
[Requirements] [int] NOT NULL,
[Status] [int] NOT NULL,
[EmergencyType] [nvarchar](50) NULL,
[EmergencyContact] [nvarchar](50) NULL,
[EmergencyNotes] [ntext] NULL,
[EmergencyTelephone] [nvarchar](50) NULL,
[Title] [nvarchar](50) NULL,
[VolunteerID] [int] NOT NULL,
[UserID] [int] NOT NULL,
[DateOfBirth] [datetime] NULL,
[HasPushPin] [bit] NULL,
[InvoiceAddress1] [nvarchar](50) NULL,
[InvoiceAddress2] [nvarchar](50) NULL,
[InvoiceTown] [nvarchar](50) NULL,
[InvoiceCounty] [nvarchar](50) NULL,
[InvoicePostcode] [nvarchar](10) NULL,
[InvoiceName] [nvarchar](50) NULL,
[Email] [nvarchar](50) NULL,
Try to change the WHERE part of your query to something like this:
WHERE
E.ClientID IN (SELECT vEvents.ClientID
FROM vEvents
GROUP BY vEvents.ClientID
HAVING SUM(vEvents.Charged) > 0)
AND ...
Maybe:
ALTER PROCEDURE [dbo].[MyReport]
#startdate datetime,
#enddate datetime
AS
/* Return the event plan (coming events) for a specific volunteer */
declare #sd datetime
declare #ed datetime
/* Ensure that the start and end dates covert whole days */
set #sd = convert(varchar(10),#startdate,120) + ' 00:00:00'
set #ed = convert(varchar(10),#enddate,120) + ' 23:59:59'
SELECT
E.EventID, E.EventDate, E.StartTime, E.StartLocation, E.EndTime,
E.EndLocation, E.Charged, E.Actual,E.ChargeRate, E.Cost,
E.Persons, E.Reason,
C.ClientID, C.Address1, C.Address2, C.Town, C.County, C.Postcode,
C.InvoiceName, C.InvoiceAddress1, C.InvoiceAddress2, C.InvoiceTown,
C.InvoiceCounty, C.InvoicePostCode,
ISNULL(C.Surname, '') + ', ' + ISNULL(C.Forename, '') AS ClientSurnameForename
FROM
vEvents E
INNER JOIN
vClients C ON E.ClientID = C.ClientID
INNER JOIN (SELECT ClientID, SUM(Charged) ch
FROM vEvents
GROUP BY ClientID
HAVING SUM(Charged) > 0) t
ON t.ClientID = vEvents.ClientID
WHERE (E.EventDate BETWEEN #sd AND #ed)
AND E.SchemeID = 4
ORDER BY
c.Surname, c.Forename, E.EventDate, E.StartTime, E.EndTime