I have the following code that creates the Checkin_day variable from CHECKIN_DATE_TIME. I'd like to only select 'Sundays' from the newly created Checkin_day variable but I'm getting an invalid column name error (because it is not a variable within the dataset). What can I add to my code so that I can select only records that fall on a 'Sunday'? Is this a declare issue or do I need to sub-query?
use EMTCQIData
DECLARE #StartDate Date
DECLARE #EndDate Date
Set #StartDate = '01/01/2018'
Set #EndDate = '12/31/2018'
SELECT *,
Format([CHECKIN_DATE_TIME],'dddd') AS [Checkin_Day]
FROM ED_TAT_MASTER
WHERE (CHECKIN_DATE_TIME > #StartDate and CHECKIN_DATE_TIME < #EndDate) AND
Checkin_Day = '*Sunday*'
Try querying the actual column, not the alias.
DECLARE #StartDate Date
DECLARE #EndDate Date
Set #StartDate = '01/01/2018'
Set #EndDate = '12/31/2018'
SELECT *,
FORMAT([CHECKIN_DATE_TIME], 'dddd') AS [Checkin_Day]
FROM
ED_TAT_MASTER
WHERE
(CHECKIN_DATE_TIME > #StartDate and CHECKIN_DATE_TIME < #EndDate)
AND FORMAT([CHECKIN_DATE_TIME], 'dddd') = 'Sunday' -- <- here
Also you can query by using DATEPART like DATEPART(dw, [CHECKIN_DATE_TIME]) = 0
https://www.w3schools.com/sql/func_sqlserver_datepart.asp
Add an AND to your WHERE clause to only get records that fall on Sunday.
Related
I have a SQL Server database with this table:
and I am trying to get RatePrice between specific dates for a certain TypeID e.g.
DECLARE #StartDate DATE = '2022-02-26';
DECLARE #EndDate DATE = '2022-03-02';
DECLARE #TypeID int = 10;
DECLARE #RatePrice money;
DECLARE #RateDate DATE;
WHILE (#StartDate <= #EndDate)
BEGIN
SELECT
#RatePrice = RatePrice,
#RateDate = #StartDate
FROM mgaRate
WHERE mgaRate.TypeID = #TypeID
AND ((RateStart BETWEEN #StartDate AND #EndDate) OR
(RateEnd BETWEEN #StartDate AND #EndDate) OR
(RateStart <= #StartDate AND RateEnd >= #EndDate)
)
PRINT #RateDate;
PRINT #RatePrice;
SET #StartDate = DATEADD(day, 1, #StartDate);
END;
But the result is not correct:
2022-02-26
400.00
2022-02-27
400.00
2022-02-28
400.00
2022-03-01
400.00
2022-03-02
400.00
In February the price should show 300.00.
You can use a calendar table to get all the dates in the range you need, and for each date you can get the rate using a subquery from the original table:
DECLARE #StartDate DATE = '2022-02-26';
DECLARE #EndDate DATE = '2022-03-02';
DECLARE #TypeID int = 10;
with calendar as (
select #StartDate as d
union all
select dateadd(day, 1, d)
from calendar
where d < #EndDate
)
select
d,
(select RatePrice
from mgaRate
where d between RateStart and RateEnd
and TypeID = #TypeID)
from calendar
You can replace the recursive CTE with an actual calendar table.
Fiddle
I have a query that a guy helped here in developing which gives fine result. I want to use this query in a function which later I want to use in a procedure.
CREATE FUNCTION [dbo].[fnGetWorkedDays] (#StartDate datetime, #EndDate datetime)
RETURNS int
AS
BEGIN
DECLARE #dateFrom datetime
DECLARE #dateTo datetime
SET #dateFrom = #StartDate
SET #dateTo = #EndDate
DECLARE #DAYSWORKED INT
SELECT #DAYSWORKED = (
SELECT EmpId, COUNT(*) as DaysWorked
FROM
(
SELECT DISTINCT EmpId,CAST(TimeIn AS DATE) AS [Date]
FROM myTable
WHERE TimeIn IS NOT NULL
AND CAST(TimeIn AS DATE) BETWEEN #StartDate AND #EndDate
)T
GROUP BY EmpId
ORDER BY EmpId)
RETURN ISNULL(#DAYSWORKED,0)
END
The very first error I am getting is that
Msg 1033, Level 15, State 1, Procedure fnGetWorkedDays, Line 24
The ORDER BY clause is invalid in views, inline functions, derived tables, subqueries, and common table expressions, unless TOP, OFFSET or FOR XML is also specified.
I removed ORDER BY then I got another error says
Msg 116, Level 16, State 1, Procedure fnGetWorkedDays, Line 25
Only one expression can be specified in the select list when the subquery is not introduced with EXISTS.
I suggest you to go though this to understand more on table valued functions vs scalar valued function Difference between scalar, table-valued, and aggregate functions in SQL server?
Regarding your scenario, you should be writing a table values function for this like following.
CREATE FUNCTION [dbo].[fnGetWorkedDays]
(
#StartDate AS DATETIME,
#EndDate datetime
)
RETURNS TABLE
AS
RETURN
SELECT EmpId, COUNT(*) as DaysWorked
FROM
(
SELECT DISTINCT EmpId,CAST(TimeIn AS DATE) AS [Date]
FROM myTable
WHERE TimeIn IS NOT NULL
AND CAST(TimeIn AS DATE) BETWEEN #StartDate AND #EndDate
)T
GROUP BY EmpId
To use the function you can write your queries like following.
DECLARE #StartDate datetime
DECLARE #EndDate datetime
SET #StartDate = '2018-01-01'
SET #EndDate = '2018-01-31'
select * from [dbo].[fnGetWorkedDays](#StartDate,#EndDate)
If you want this to work as a scalar value function, in that case you need to pass EmpId as parameter like following.
CREATE FUNCTION [dbo].[fnGetWorkedDaysEmpWise]
(
#StartDate AS DATETIME,
#EndDate datetime,
#EmpId INT
)
RETURNS INT
AS
BEGIN
DECLARE #RetunCount INT
SELECT #RetunCount = COUNT(DISTINCT CAST(TimeIn AS DATE))
FROM myTable
WHERE TimeIn IS NOT NULL
AND CAST(TimeIn AS DATE) BETWEEN #StartDate AND #EndDate
AND EmpID=#EmpId
RETURN #RetunCount
END
And you can use it directly in your select clause like following.
DECLARE #StartDate datetime
DECLARE #EndDate datetime
SET #StartDate = '2018-01-01'
SET #EndDate = '2018-01-31'
SELECT [dbo].[fnGetWorkedDaysEmpWise](#StartDate,#EndDate,1)
Is this what you are looking for .?
CREATE FUNCTION [dbo].[fnGetWorkedDays] (#StartDate datetime, #EndDate datetime)
RETURNS #DaysWorked TABLE
(
Empid Int,
DaysWorked Int
)
AS
BEGIN
insert into #DaysWorked (Empid,DaysWorked)
SELECT EmpId, COUNT(*) as DaysWorked
FROM
(
SELECT DISTINCT EmpId,CAST(TimeIn AS DATE) AS [Date]
FROM myTable
WHERE TimeIn IS NOT NULL
AND CAST(TimeIn AS DATE) BETWEEN #StartDate AND #EndDate
)T
GROUP BY EmpId
ORDER BY EmpId
RETURN
END
select * from [fnGetWorkedDays]('2018-01-01','2018-01-31')
I am trying to create my SQL syntax so that we can have versatile input. I figured out how to do it for one set date and it worked.
my syn is:
DECLARE #MyDay AS VARCHAR(50);
DECLARE #NextDay AS VARCHAR(50);
SET #MyDay = '8/30/2016';
SET #NextDay = DATEADD(d, 1, #MyDay);
However, I'm stuck with how to do it for multiple dates. Ideally I would like to put in a range of date, and from that it will scan the records, i.e. set range between oct 1st and oct 5th.
I'm using SQL Server Management Studio 2008
If you just want a series of days and next days between 8/30/16 and 9/5/16, you can use a derive table method like below.
declare #n int;
declare #StartDate datetime, #EndDate datetime;
set #n = 5;
set #StartDate = '20160830';
set #EndDate = dateadd(day, #n, #StartDate);
select cast(dateadd(day, number, #StartDate) as date) as MyDate,
cast(dateadd(day, number + 1, #StartDate) as date) as MyNextDate
from
(select distinct number from master.dbo.spt_values
where name is null
) n
where dateadd(day, number, #StartDate) < #EndDate;
Alternately you can use a temp table, table variable to store your dates, or a cte as well.
A recursive cte imlementation example is given below. Please note you would want to set MAXRECURSION option if you have a long date range as default for max recursion is 100.
declare #n int;
declare #StartDate datetime, #EndDate datetime;
set #n = 5;
set #StartDate = '20160830';
set #EndDate = dateadd(day, #n, #StartDate);
;with DateSeq as
(
select cast(#StartDate as date) as MyDate
union all
select dateadd(day , 1, MyDate) AS MyDate
from DateSeq where dateadd (day, 1, MyDate) < #EndDate
)
select MyDate, dateadd(day , 1, MyDate) AS NextDate
from DateSeq;
A temp table implementation example is as below.
declare #MyDateRange table(MyDate date);
Insert into #MyDateRange values('8/30/2016')
Insert into #MyDateRange values('9/1/2016')
Insert into #MyDateRange values('9/2/2016')
Insert into #MyDateRange values('9/3/2016')
Insert into #MyDateRange values('9/4/2016')
select MyDate, dateadd(day, 1, MyDate) as NextDate from #MyDateRange
I'm trying to create a report with iReport by using below query which runs fine on SSRS reports. I'm new to JasperReports. How can I declare variables inside the report query? Here is my SQL query:
Declare #SDate as Date
Declare #EDate as Date
Declare #JNumber as Char(8)
set #SDate = case When #StartDate > '1/1/2000' Then #StartDate Else GETDATE() End
set #EDate = case When #EndDate > '1/1/2000' Then #EndDate Else GETDATE() End
set #JNumber = ISNULL(#JobNumber, '')
select Distinct
j.JobNumber, j.CustomerRep, j.JobStatus, j.StatusDate, a.Answer14 'Ship Time' ,j.LastShippedDate, Cast(m.ExpectedDate as Date) 'ShipDate',
m.CustomerCode, RTrim(m.CustLongName) , RTrim(m.[Description]) 'JobName', RTrim(m.PONumber) 'PONumber', m.ProductCode, m.QuantityOrdered, a1.answer8'Pages'
from JobExtra j (NOLOCK)
Join JobMaster m (nolock) on m.JobNumber = j.JobNumber
where (#JNumber != '' AND #JNumber = j.JobNumber)
And #SDate <= Cast(ISNULL(ce.sStartDate, m.StartDate) As Date)
And #EDate >= Cast(ISNULL(ce.sStartDate, m.StartDate) As Date)
order by Case When #Sort = 'Ship Date' Then m.ExpectedDate When #Sort = 'Start Date' Then m.StartDate Else j.JobNumber End
, j.JobNumber, ce.sEndDate, ce.sEndTime, ce.sStartDate
The error is:
Error:java.sql.SQLException:Must Declare the scalar variable #StartDate
Seems like you have missed two variables.Please Declare variables #StartDate And #EndDate similarly like #SDate and #Edate
Ex:
Declare #StartDate Date
Declare EndDate Date
Please try it once
Thanks,
Dhana
How can I create a method to subtract two dates and this is equal to in real date as format datetime2(7) in sql server 2008.
For example ,I create this method:
Delete from TblMessage
Where MDateTime<((SELECT TOP (1)MDateTime FROM TblMessage ORDER BY MDateTime DESC)- ('2013-10-04 16:47:56.0000000'))
but it is not working .I want to result of subtract two date like this:
MDateTime1:2013-10-05 16:47:56.0000000
MDateTime2:2013-09-04 16:47:56.0000000
Result:2013-01-01 00:00:00.0000000
Result=MDateTime1-MDateTime2
How can I do this. Thanks...
Perhaps you are looking for this?
select DATEADD( day, datediff(day,GETDATE(), getdate() - 10), GETDATE() ) ;
DATEDIFF(dayofyear,MDateTime1,MDateTime2) AS Result
http://msdn.microsoft.com/en-us/library/ms189794.aspx
DECLARE
#DATE1 DATETIME = '2013-10-05 16:47:56.000',
#DATE2 DATETIME = '2013-09-04 17:37:42.000',
#DATEDIFF AS INT,
#BASEDATE DATETIME;
-- USE WHAT EVER DATE YOU WISH TO BE YOUR BASE DATE
SET #BASEDATE = '1/1/1900';
SET #DATEDIFF = DATEDIFF(SECOND, #DATE2, #DATE1);
SELECT #DATE1,#DATE2,#DATEDIFF, DATEADD(SECOND,#DATEDIFF,#BASEDATE)
Thus a scalar function could be created like this...
CREATE FUNCTION dbo.sf_GetMeasureDate
(
#EndDate DATETIME,
#StartDate DATETIME,
#BaseDate DATETIME
)
RETURNS DATETIME
AS
BEGIN
DECLARE #DATEDIFF AS INT
SET #DATEDIFF = DATEDIFF(SECOND, #StartDate, #EndDate);
Return DATEADD(SECOND,#DATEDIFF,#BASEDATE)
END
GO
Then within you regular SELECT statement you can call the function as such.
SELECT dbo.sf_GetMeasureDate('2013-10-05 16:47:56.000','2013-09-04 17:37:42.000','1/1/1900')
or within an existing query:
SELECT dbo.sf_GetMeasureDate([fld1],[fld2],'1/1/1900')