I am using SSRS 2008 and i have a stored proc which currently uses cursors to delete and add data, but even after I convert this to select queries, I am getting error:
Msg 102, Level 15, State 1, Line 39
Incorrect syntax near ')'.
Here was the original Cursor which worked:
OPEN PARTS
FETCH PARTS INTO #PART_NUM,
#PART_DESC
SET #PARTS_FETCH = ##FETCH_STATUS
WHILE #PARTS_FETCH = 0 BEGIN
SET #THE_DATE = dateadd("yy", -1, dateadd("m", -1, getdate()))
SET #END_DATE = DATEADD(ms, -5, DATEADD(mm, DATEDIFF(m, 0, getdate()) + 1, 0))
-- Get PL for part number
Delete from #tbl_PL
Insert #tbl_PL
SELECT FRUD.tblXref.product_code FROM FRUD.tblfieldOrderablePart INNER JOIN
FRUD.MAX_APPROVED ON FRUD.tblfieldOrderablePart.fop_no = FRUD.MAX_APPROVED.fop_no AND
FRUD.tblfieldOrderablePart.fop_revision = FRUD.MAX_APPROVED.MaxOffop_revision INNER JOIN
FRUD.tblXref ON FRUD.MAX_APPROVED.fop_no = FRUD.tblXref.fop_no AND
FRUD.MAX_APPROVED.MaxOffop_revision = FRUD.tblXref.fop_revision
WHERE (dbo.FORMAT_PART(FRUD.tblfieldOrderablePart.fop_no) = dbo.FORMAT_PART(#PART_NUM))
-- End Get PL
WHILE #THE_DATE <= #END_DATE BEGIN
SET #THE_DATE = DATEADD(ms, -5, DATEADD(mm, DATEDIFF(m, 0, #THE_DATE) + 1, 0))
-- Get census using PL
SELECT #ALL_TOTAL = SUM(TheSum) FROM (SELECT CAST(RELIABILITY.Census.Census AS DECIMAL(9,2)) AS TheSum, (CONVERT(datetime, LEFT(CONVERT(char, Period), 4) + '-' + RIGHT(Period, 2) + '-1', 102)) as ThePeriod
FROM RELIABILITY.Census
WHERE RELIABILITY.Census.PL In (Select distinct * FROM #tbl_PL)
AND (CONVERT(datetime, LEFT(CONVERT(char, Period), 4) + '-' + RIGHT(Period, 2) + '-1', 102) >=
DATEADD(mm, DATEDIFF(mm, 0, #THE_DATE) - 5, 0)) AND (CONVERT(datetime, LEFT(CONVERT(char, Period), 4)
+ '-' + RIGHT(Period, 2) + '-1', 102) <= #THE_DATE) UNION ALL SELECT CAST(Census AS DECIMAL(9,2)) AS TheSum, Period FROM [MANUAL].SMARTSOLVE_CENSUS WHERE (Period >= DATEADD(mm, DATEDIFF(mm, 0, #THE_DATE) - 5, 0) AND Period <= #THE_DATE) AND (PL In (Select distinct * FROM #tbl_PL)))A
And here is my conversion to Select:
DECLARE #THE_DATE datetime,
#END_DATE datetime,
#THE_GOAL decimal(18,2),
#PART_NUM nvarchar(50),
#UNCHANGED_PART_NUM nvarchar(50),
#PART_DESC varchar(35),
#PARTS_FETCH int,
#NUM_FAILED int,
#AVG_CENSUS decimal(18,2),
#PL_VAR nvarchar(50),
#PL_FETCH int,
#PL_TOTAL decimal(9,2),
#ALL_TOTAL decimal(9,2)
--WHILE #PARTS_FETCH = 0 BEGIN
SET #THE_DATE = dateadd("yy", -1, dateadd("m", -1, getdate()))
SET #END_DATE = DATEADD(ms, -5, DATEADD(mm, DATEDIFF(m, 0, getdate()) + 1, 0))
--WHILE #THE_DATE <= #END_DATE BEGIN
SET #THE_DATE = DATEADD(ms, -5, DATEADD(mm, DATEDIFF(m, 0, #THE_DATE) + 1, 0))
-- Get census using PL
SELECT #ALL_TOTAL = SUM(TheSum) FROM
(SELECT CAST(RELIABILITY.Census.Census AS DECIMAL(9,2)) AS TheSum
from RELIABILITY.Census
WHERE RELIABILITY.Census.PL In (Select distinct * FROM #tbl_PL)
AND (CONVERT(datetime, LEFT(CONVERT(char, Period), 4) + '-' + RIGHT(Period, 2) + '-1', 102) >=
DATEADD(mm, DATEDIFF(mm, 0, #THE_DATE) - 5, 0)) AND (CONVERT(datetime, LEFT(CONVERT(char, Period), 4)+ '-' + RIGHT(Period, 2) + '-1', 102) <= #THE_DATE)
UNION ALL
SELECT CAST(Census AS DECIMAL(9,2)) AS TheSum, Period
FROM [MANUAL].SMARTSOLVE_CENSUS
WHERE (Period >= DATEADD(mm, DATEDIFF(mm, 0, #THE_DATE) - 5, 0) AND Period <= #THE_DATE) AND (PL In (Select distinct * FROM #tbl_PL))
))A
As Joel and Lamak pointed out you have an extra ) This is actually really easy to find if you use something like Instant SQL formatter This will give the error
)(11,3) expected token:Unknown
)(11,3) expected token:
It also formats the SQL as below which makes it a little easier to follow.
SELECT #ALL_TOTAL = SUM(thesum)
FROM (SELECT CAST(reliability.census.census AS DECIMAL(9, 2)) AS thesum
FROM reliability.census
WHERE reliability.census.pl IN (SELECT DISTINCT *
FROM #tbl_pl)
AND ( CONVERT(DATETIME, LEFT(CONVERT(CHAR, period), 4) + '-' +
RIGHT(
period, 2)
+
'-1'
, 102) >= Dateadd(mm, Datediff(mm, 0, #THE_DATE) - 5, 0) )
AND ( CONVERT(DATETIME, LEFT(CONVERT(CHAR, period), 4)+ '-' +
RIGHT(
period, 2) +
'-1',
102) <= #THE_DATE )
UNION ALL
SELECT CAST(census AS DECIMAL(9, 2)) AS thesum,
period
FROM [MANUAL].smartsolve_census
WHERE ( period >= Dateadd(mm, Datediff(mm, 0, #THE_DATE) - 5, 0)
AND period <= #THE_DATE )
AND ( pl IN (SELECT DISTINCT *
FROM #tbl_pl) ))a
Sounds like you have mis-matched parentheses, double check and make sure they all line up correctly. You have one more ")" at the end of that last select statement than you have ever being opened. That's a lot of nesting! Make sure everything matches up how you intended, or you may get unexpected results if your UNION gets applied at the wrong level or something.
If I'm reading your query correctly, you have two errors. The first is an extra ")" on the last line, it should be:
WHERE (Period >= DATEADD(mm, DATEDIFF(mm, 0, #THE_DATE) - 5, 0) AND Period <= #THE_DATE) AND (PL In (Select distinct * FROM #tbl_PL))
) A
And, I think you also have more columns on your query after the UNION ALL, you are selecting CAST(Census AS DECIMAL(9,2)) AS TheSum, Period and on the first one you are selecting only one column: CAST(RELIABILITY.Census.Census AS DECIMAL(9,2)) AS TheSum
Related
SELECT Clmn
FROM Tbl T
INNER JOIN SomeotherTbl
WHERE CONVERT(varchar(10), T.[Date], 120) =
CASE #SortOrder
WHEN '1' THEN CONVERT(varchar(10), GETDATE(), 120)
WHEN '2' THEN CONVERT(varchar(7), GETDATE(), 120)
WHEN '3' THEN CONVERT(varchar(4), GETDATE(), 120)
END
So i have a Date column that i converted to varchar , but i would like to convert it to different length according to #SortOrder , what's the best solution ?
Use Like instead of =:
WHERE CONVERT(varchar(10),D.[Date],120) LIKE
CASE #SortOrder
WHEN '1' THEN CONVERT(varchar(10),GETDATE(),120)
WHEN '2' THEN CONVERT(varchar(7),GETDATE(),120) +'%'
WHEN '3' THEN CONVERT(varchar(4),GETDATE(),120) +'%'
END
Another option (without using case) is this:
WHERE (#SortOrder > '3' OR YEAR(D.[Date]) = YEAR(GETDATE()))
AND (#SortOrder > '2' OR MONTH(D.[Date]) = MONTH(GETDATE()))
AND (#SortOrder > '1' OR DAY(D.[Date]) = DAY(GETDATE()))
And yet another option, that will work for versions 2012 or higher, and is a little more complicated, but if you have an index on the [Date] column will allow SQL Server to use it:
DECLARE #Date date = GETDATE()
DECLARE #ThisMonth date = DATEFROMPARTS(YEAR(#Date), MONTH(#Date), 1)
DECLARE #ThisYear date = DATEFROMPARTS(YEAR(#Date), 1, 1)
SELECT ...
FROM ...
WHERE
(#SortOrder = '1' AND D.[Date] = #Date)
OR (#SortOrder = '2' AND D.[Date] >= #ThisMonth AND D.[Date] < DATEADD(MONTH, 1, #ThisMonth))
OR (#SortOrder = '3' AND D.[Date] >= #ThisYear AND D.[Date] < DATEADD(YEAR, 1, #ThisYear))
You can see a live demo on rextester.
If you want to compare year, month, and day there are better ways
select CONVERT(varchar(10), GETDATE(), 120), CONVERT(varchar(7), GETDATE(), 120), CONVERT(varchar(4), GETDATE(), 120)
, DATEPART(year, getdate()), DATEPART(month, getdate()), DATEPART(day, getdate())
2018-02-22 2018-02 2018 2018 2 22
I have a query that i have been tinkering with to use as a source for a report.
For some odd reason when i try to compare the output of datepart(dw,GetDate()) to an integer (2 for Monday) it gives me an error telling me incorrect syntax. i then started looking into why i couldn't compare two integers in an iif statement and... i have found absolutely no answers.
here is the full code (i went back and forth on how to do this, this is this iterations attempt)
DECLARE #dp integer,#d integer
set #dp =DATEpart(dw,GETDATE())
set #d = 2
SELECT TOP 100 PERCENT CUST_ORDER_LINE.PRODUCT_CODE
,CUSTOMER_ORDER.ID
,CUSTOMER_ORDER.CUSTOMER_ID
,CUST_ORDER_LINE.PART_ID
,CUST_ORDER_LINE.MISC_REFERENCE
,CUST_ORDER_LINE.COMMODITY_CODE
,CUSTOMER_ORDER.SALESREP_ID
,CUSTOMER_ORDER.TERRITORY
,CUST_ORDER_LINE.ORDER_QTY * CUST_ORDER_LINE.UNIT_PRICE AS Amount
,CUSTOMER_ORDER.ORDER_DATE
FROM CUST_ORDER_LINE
INNER JOIN CUSTOMER_ORDER ON CUST_ORDER_LINE.CUST_ORDER_ID = CUSTOMER_ORDER.ID
WHERE (
iif(#dp = #d,CUSTOMER_ORDER.ORDER_DATE BETWEEN ( dateadd(day, datediff(day, 0, getdate()), 0) - 3) AND ( dateadd(day, datediff(day, 0, getdate()),0))),
CUSTOMER_ORDER.ORDER_DATE BETWEEN ( dateadd(day, datediff(day, 0, getdate()), 0) - 1)) AND ( dateadd(day, datediff(day, 0, getdate()), + 1))))
)
ORDER BY CUSTOMER_ORDER.ORDER_DATE DESC
The point of this query is to pull data from yesterday, and Friday if it is Monday.
EDIT: error code Msg 170, Level 15, State 1, Line 19
Line 19: Incorrect syntax near '='.
IIF is in 2012. You can try using CASE instead.
DECLARE #dp integer,#d integer
set #dp =DATEpart(dw,GETDATE())
set #d = 2
SELECT TOP 100 PERCENT CUST_ORDER_LINE.PRODUCT_CODE
,CUSTOMER_ORDER.ID
,CUSTOMER_ORDER.CUSTOMER_ID
,CUST_ORDER_LINE.PART_ID
,CUST_ORDER_LINE.MISC_REFERENCE
,CUST_ORDER_LINE.COMMODITY_CODE
,CUSTOMER_ORDER.SALESREP_ID
,CUSTOMER_ORDER.TERRITORY
,CUST_ORDER_LINE.ORDER_QTY * CUST_ORDER_LINE.UNIT_PRICE AS Amount
,CUSTOMER_ORDER.ORDER_DATE
FROM CUST_ORDER_LINE
INNER JOIN CUSTOMER_ORDER ON CUST_ORDER_LINE.CUST_ORDER_ID = CUSTOMER_ORDER.ID
WHERE
CUSTOMER_ORDER.ORDER_DATE BETWEEN CASE
WHEN #dp = #d THEN ( dateadd(day, datediff(day, 0, getdate()), 0) - 3)
ELSE ( dateadd(day, datediff(day, 0, getdate()), 0) - 1)
END
AND CASE
WHEN #dp = #d THEN ( dateadd(day, datediff(day, 0, getdate()),0))
ELSE ( dateadd(day, datediff(day, 0, getdate()), + 1))
END
ORDER BY CUSTOMER_ORDER.ORDER_DATE DESC
for the below query i need divide the semesters starting from 1 to 26 .. first semester as 1 to 26 weeks and first semester should start from again 1 to 26
Any help is greating appreciated
DECLARE #StartDate DATETIME
DECLARE #CutoffDate DATETIME
SET #StartDate = Dateadd(yy, Datediff(yy, 0, Getdate()), 0)
SET #CutoffDate = Dateadd(yy, Datediff(yy, 0, Getdate()) + 1, -1)
SELECT day,
[week nu],
semester,
[semester week nu]
INTO #currentdates
FROM (SELECT Day = Dateadd(day, rn - 1, #StartDate),
Datepart(week, Dateadd(day, rn - 1, #StartDate)) [Week nu],
CASE
WHEN Month(Dateadd(day, rn - 1, #StartDate)) <= 6 THEN
'First Semester'
ELSE 'Second Semester'
END AS Semester,
Datepart(week, Dateadd(day, rn - 1, #StartDate)) AS
[Semester Week nu]
FROM (SELECT TOP (Datediff(day, #StartDate, #CutoffDate)) rn =
Row_number()
OVER (
ORDER BY s1.[object_id])
FROM sys.all_objects AS s1
CROSS JOIN sys.all_objects AS s2
ORDER BY s1.[object_id]) AS x) AS y;
I've got a couple of changes, first, you need to add 1 to your last datediff, your last date was December 30, not 31!
Second of all, I just get the date and week number in the first subselect, and then use these ine case statements for the select
The semester number is if week nu<=26,
The semester week nu is week nu if week nu<=26 else wwek nu -26
DECLARE #StartDate datetime DECLARE #CutoffDate datetime
SET #StartDate = DATEADD(yy, DATEDIFF(yy, 0, GETDATE()), 0)
SET #CutoffDate = DATEADD(yy, DATEDIFF(yy, 0, GETDATE()) + 1, -1)
SELECT DAY,
[Week nu],
case when [Week nu]<=26 then 'First Semester' Else 'Second Semester' end Semester,
case when [Week nu]<=26 then [Week nu] Else [Week nu]-26 end[Semester Week nu]
INTO #currentDates
FROM
(SELECT DAY = DATEADD(DAY, rn - 1, #StartDate),
DATEPART(WEEK,DATEADD(DAY, rn - 1, #StartDate)) [Week nu]
FROM
(SELECT TOP (DATEDIFF(DAY, #StartDate, #CutoffDate)+1) rn = ROW_NUMBER() OVER (ORDER BY s1.[object_id])
FROM sys.all_objects AS s1
CROSS JOIN sys.all_objects AS s2
ORDER BY s1.[object_id]) AS x) AS y;
I'm trying to query data within a range of start year and month and end year and month. But SQL returnes onty the year and the month chosen. Can anyone identify the problem with my approach.
Thanks!
ALTER PROCEDURE xxx
(#JaarBegin AS int
, #JaarEind AS int
, #MaandBegin AS int
, #MaandEind AS int)
AS
BEGIN
WITH
CTE AS
(
SELECT [D_Medewerker_ID]
,[Gebruikersnaam]
,[Naam]
,[Afdelingscode]
,CONVERT(date, [Datum_uit_dienst]) AS DatumIn
,CONVERT(date, [Datum_in_dienst]) AS DatumUit
FROM [DM].[dm].[D_Medewerker] AS M
),
CTE2 AS(
SELECT F.[D_Functie_ID]
,[Generieke_Functie]
,[Specifieke_Functie]
,Fo.[D_Medewerker_ID]
FROM [DM].[dm].[D_Functie] AS F
JOIN dm.dm.F_FormatieBezetting AS Fo
ON F.D_Functie_ID = Fo.D_Functie_ID
)
SELECT DISTINCT CTE.[Gebruikersnaam]
, CTE.Naam
, CTE.Afdelingscode
, CTE.DatumIn
, CTE.DatumUit
, CTE2.Generieke_Functie
, CTE2.Specifieke_Functie
FROM CTE
JOIN CTE2
ON CTE.D_Medewerker_ID = CTE2.D_Medewerker_ID
WHERE DATEPART(year,CTE.DatumUit) BETWEEN #JaarBegin AND #JaarEind
AND DATEPART(MONTH, CTE.DatumUit) >= #MaandBegin AND DATEPART(MONTH, CTE.DatumUit) <= #MaandEind
ORDER BY CTE.DatumUit DESC;
END
You need to convert the int values you get to a date value.
In Sql server 2012 or later, you can use the built-in function DATEFROMPARTS to do this:
WHERE CTE.DatumUit >= DATEFROMPARTS ( #JaarBegin , #MaandBegin , 1 )
AND CTE.DatumUit < DATEADD(MONTH, 1, DATEFROMPARTS ( #JaarEind , #MaandBegin , 1 ))
If you are working with an earlier version of sql server, you need to build a string that represents the date (using iso format yyyy-mm-dd) and then cast it to date:
WHERE CTE.DatumUit >= CAST(RIGHT('0000' + CAST(#JaarBegin as varchar(4)), 4) + '-' + RIGHT('00' + CAST(#MaandBegin as varchar(2)), 2) +'-01' as datetime)
AND CTE.DatumUit < DATEADD(MONTH, 1, CAST(RIGHT('0000' +CAST(#JaarEind as varchar(4)), 4) + '-' + RIGHT('00' + CAST(#MaandBegin as varchar(2)), 2) +'-01' as datetime))
I'm trying to get ordinance by the current date from a table. this query does what I want but it seems overkill:
WITH dates
AS (SELECT Month,
FQ,
FY,
MonthDisplay,
CAST (datepart(yyyy, [Month]) AS VARCHAR) + '-' + RIGHT(CAST ((datepart(MM, [Month]) + 100) AS VARCHAR), 2) AS YM,
fh,
LEFT(CONVERT (VARCHAR, [Month], 100), 3) + ' ' + RIGHT(fy, 4) AS MY,
LEFT(CONVERT (VARCHAR, [Month], 100), 3) AS ShortMonthName
FROM Pipeline.DimTime AS dt),
datesafter
AS (SELECT dt.FH,
dt.FQ,
dt.FY,
dt.MY,
dt.Month,
dt.MonthDisplay,
dt.ShortMonthName,
dt.YM,
ROW_NUMBER() OVER ( ORDER BY [Month]) AS RowNum
FROM dates AS dt
WHERE dt.[Month] >= (SELECT TOP 1 DATEADD(MONTH, DATEDIFF(MONTH, 0, ds.SnapshotDate), 0)
FROM dbo.vw_DimSnapshot AS ds
WHERE ds.SnapshotWeek = 'Current')),
datesbefore
AS (SELECT dt.FH,
dt.FQ,
dt.FY,
dt.MY,
dt.Month,
dt.MonthDisplay,
dt.ShortMonthName,
dt.YM,
(ROW_NUMBER() OVER ( ORDER BY [Month] DESC)) * -1 AS RowNum
FROM dates AS dt
WHERE dt.[Month] < (SELECT TOP 1 DATEADD(MONTH, DATEDIFF(MONTH, 0, ds.SnapshotDate), 0)
FROM dbo.vw_DimSnapshot AS ds
WHERE ds.SnapshotWeek = 'Current'))
SELECT *
FROM datesafter
UNION ALL
SELECT *
FROM datesbefore
ORDER BY [month];
I think you can do it in a single query by using datediff. Pass current date as one parameter and the table date as another. This will work if you are ok with skipping missing dates. For example if current date is Nov 21, then Nov 20 will show up as -1 and Nov 18 will show up as -3 even if Nov 19 is missing in the data. I am not sure what your business requirement is, so cannot comment beyond that.
And by the way if you are looking for ordinance based on months instead of day, you can use still use datediff but use the correct datepart (See: http://msdn.microsoft.com/en-us/library/ms189794.aspx).
HTH.
-Tabrez