I have a query and I just want to modify it (This query is not written by me).
SELECT CAST(DATEPART(yyyy, UTCTimeStamp) AS VARCHAR(4)) + '-'
+ CAST(DATEPART(mm, UTCTimeStamp) AS VARCHAR(2)) + '-'
+ CAST(DATEPART(dd, UTCTimeStamp) AS VARCHAR(2)) + ' '
+ CAST(DATEPART(hh, UTCTimeStamp) AS VARCHAR(2)) + ':00:000 - '
+ CAST(DATEPART(yyyy, UTCTimeStamp) AS VARCHAR(4)) + '-'
+ CAST(DATEPART(mm, UTCTimeStamp) AS VARCHAR(2)) + '-'
+ CAST(DATEPART(dd, UTCTimeStamp) AS VARCHAR(2)) + ' '
+ CAST(DATEPART(hh, UTCTimeStamp) AS VARCHAR(2)) + ':45:000' AS HourTime ,
SUM(CASE WHEN ElapsedValue IS NULL THEN 1
ELSE 0
END) AS NoData ,
SUM(CASE WHEN ElapsedValue = 0 THEN 1
ELSE 0
END) AS ZeroData
FROM tblLive_TrendLog_15Min
WHERE ISNULL(ElapsedValue, 0) = 0
GROUP BY CAST(DATEPART(yyyy, UTCTimeStamp) AS VARCHAR(4)) + '-'
+ CAST(DATEPART(mm, UTCTimeStamp) AS VARCHAR(2)) + '-'
+ CAST(DATEPART(dd, UTCTimeStamp) AS VARCHAR(2)) + ' '
+ CAST(DATEPART(hh, UTCTimeStamp) AS VARCHAR(2)) + ':00:000 - '
+ CAST(DATEPART(yyyy, UTCTimeStamp) AS VARCHAR(4)) + '-'
+ CAST(DATEPART(mm, UTCTimeStamp) AS VARCHAR(2)) + '-'
+ CAST(DATEPART(dd, UTCTimeStamp) AS VARCHAR(2)) + ' '
+ CAST(DATEPART(hh, UTCTimeStamp) AS VARCHAR(2)) + ':45:000'
When I run this query, it is going to display:
HourlyTime ZeroData NULL
2013-6-8 23:00:000 - 2013-6-8 23:45:000 0 40
2013-6-8 3:00:000 - 2013-6-8 3:45:000 0 52
2013-6-8 7:00:000 - 2013-6-8 7:45:000 0 52
2013-6-9 3:00:000 - 2013-6-9 3:45:000 0 52
2013-6-9 4:00:000 - 2013-6-9 4:45:000 0 52
2010-1-1 12:00:000 - 2010-1-1 12:45:000 0 36
2010-1-1 13:00:000 - 2010-1-1 13:45:000 0 27
2010-1-1 15:00:000 - 2010-1-1 15:45:000 0 30
Basically it is calculating the zero and null values per hour. If you want to know more about it this is the link:
SQL Programming combining 4 rows into 1 and adding 3 columns
Now, I just want to add another column to that query that would calculate
if there are any constant values then just display the number of the constant values (should be between 0 and 3) for example if the value at 2013-05-4 10:30 has the same value at 2013-05-4 10:15 then should be 1 in the ConstantData column. basically, compare the value to the previous value every 15 minutes.
I believe this is a duplicate question, but just wanted to point out that with SQL 2012 you could greatly simplify your query with the FORMAT function:
SELECT FORMAT(UTCTimeStamp ,'yyyy-MM-dd hh:00:000 - yyyy-MM-dd hh:45:000 ')AS HourTime ,
SUM(CASE WHEN ElapsedValue IS NULL THEN 1
ELSE 0
END) AS NoData ,
SUM(CASE WHEN ElapsedValue = 0 THEN 1
ELSE 0
END) AS ZeroData
FROM tblLive_TrendLog_15Min
WHERE ISNULL(ElapsedValue, 0) = 0
GROUP BY FORMAT(UTCTimeStamp ,'yyyy-MM-dd hh:00:000 - yyyy-MM-dd hh:45:000 ')
Related
Consider the following code.
create table #temp (Min_Expr_InMonths int, Max_Expr_InMonths int)
insert into #temp values (40, 98)
insert into #temp values (null, null)
insert into #temp values (0, 0)
insert into #temp values (133, 145)
select ' (Exp - ' +
Convert(varchar, Case when j.Min_Expr_InMonths/12 < 10 then '0' + convert(varchar, j.Min_Expr_InMonths/12) else j.Min_Expr_InMonths/12 end) + '/' +
Convert(varchar,
case when j.Min_Expr_InMonths - ((j.Min_Expr_InMonths/12)*12) < 10 then '0' + convert(varchar, j.Min_Expr_InMonths - ((j.Min_Expr_InMonths/12)*12)) else
j.Min_Expr_InMonths - ((j.Min_Expr_InMonths/12)*12) end) + ' to ' + Convert(varchar,
Case when j.Max_Expr_InMonths/12 < 10 then '0' + convert(varchar, j.Max_Expr_InMonths/12) else j.Max_Expr_InMonths/12 end) + '/' +
Convert(varchar,
case when j.Max_Expr_InMonths - ((j.Max_Expr_InMonths/12)*12) < 10 then '0' + convert(varchar, j.Max_Expr_InMonths - ((j.Max_Expr_InMonths/12)*12)) else
j.Max_Expr_InMonths - ((j.Max_Expr_InMonths/12)*12) end) + ')' from #temp j
Output of the above query is as follows.
YY/MM
(Exp - 3/4 to 8/2)
NULL
(Exp - 0/0 to 0/0)
(Exp - 11/1 to 12/1)
What I wanted to achieve is as follows.
YY/MM
(Exp - 03/04 to 08/02)
(Exp - 00/00 to 00/00)
(Exp - 00/00 to 00/00)
(Exp - 11/01 to 12/01)
Is there a simpler way to achieve this, my query looks very untidy and difficult to read, also I am not sure about the performance as the DB rows increase.
Please Try below simplest query:
select 'Exp - ' +
right('00' + convert(varchar(2),coalesce(Min_Expr_InMonths,0)/12),2) + '/' +
right('00' + convert(varchar(2),coalesce(Min_Expr_InMonths,0)%12),2) + ' to '+
right('00' + convert(varchar(2),coalesce(Max_Expr_InMonths,0)/12),2) + '/' +
right('00' + convert(varchar(2),coalesce(Max_Expr_InMonths,0)%12),2) as 'YY/MM'
from #temp
Corrected select query:
SELECT '(Exp - ' +
CASE
WHEN j.Min_Expr_InMonths IS NULL
THEN '00'
WHEN (j.Min_Expr_InMonths/12 >= 10)
THEN CONVERT(VARCHAR, j.Min_Expr_InMonths/12)
ELSE
CONCAT('0',CONVERT(VARCHAR, j.Min_Expr_InMonths/12))
END
+ '/' +
CASE
WHEN j.Min_Expr_InMonths IS NULL
THEN '00'
WHEN j.Min_Expr_InMonths - ((j.Min_Expr_InMonths/12)*12) >= 10
THEN CONVERT(VARCHAR,j.Min_Expr_InMonths - ((j.Min_Expr_InMonths/12)*12))
ELSE
CONCAT('0',CONVERT(VARCHAR, j.Min_Expr_InMonths - ((j.Min_Expr_InMonths/12)*12)))
END
+ ' to ' +
CASE
WHEN j.Max_Expr_InMonths IS NULL
THEN '00'
WHEN j.Max_Expr_InMonths/12 >= 10
THEN CONVERT(VARCHAR, j.Max_Expr_InMonths/12)
ELSE
CONCAT('0',j.Max_Expr_InMonths/12)
END
+ '/' +
CASE
WHEN j.Max_Expr_InMonths IS NULL
THEN '00'
WHEN j.Max_Expr_InMonths - ((j.Max_Expr_InMonths/12)*12) >= 10
THEN CONVERT(VARCHAR, j.Max_Expr_InMonths - ((j.Max_Expr_InMonths/12)*12))
ELSE
CONCAT('0',CONVERT(VARCHAR,j.Max_Expr_InMonths - ((j.Max_Expr_InMonths/12)*12)))
END
+ ')'
FROM #temp j
OUTPUT
(Exp - 03/04 to 08/02)
(Exp - 00/00 to 00/00)
(Exp - 00/00 to 00/00)
(Exp - 11/01 to 12/01)
For Demo Follow the link:
http://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=d462f3f8cc4b945e01a7d594b016a105
How to Add First for 1 to 10 dates for a month and Add Last for 20 to 30 days of month.
DECLARE #Today DATE = '2016-11-05'
Select CONVERT(VARCHAR(5),datepart (DW, #Today)-1 )+' DAYS of '+ LEFT(DATENAME(month,#Today),3) Comments
I'm getting like this
Comments
6 DAYS of Nov
How to get like this :
Comments
First 6 DAYS of Nov
if I give date as '2016-11-24'
need output like this
Comments
Last 4 DAYS of Nov
Suggest me the way to proceed
Use a case statement:
Select (CASE WHEN day(#today) <= 10 THEN 'First '
WHEN day(#today) >= 20 THEN 'Last '
ELSE ''
END) + CONVERT(VARCHAR(5), datepart(DW, #Today)-1 ) + ' DAYS of ' +
LEFT(DATENAME(month, #Today), 3) as Comments
EDIT:
Oh, now I see the original query was not right. So you want something more like this:
Select (CASE WHEN day(#today) <= 10 THEN 'First ' + DATENAME(day, #today) + ' DAYS of ' + LEFT(DATENAME(month, #Today), 3)
WHEN day(#today) >= 20 AND MONTH(#Today) IN (1, 3, 5, 7, 8, 10, 12) THEN 'Last ' + CAST(31 - day(#today) as varchar(255))
WHEN day(#today) >= 20 AND MONTH(#Today) IN (4, 6, 9, 11) THEN 'Last ' + CAST(30 - day(#today) as varchar(255))
WHEN day(#today) >= 20 AND MONTH(#Today) IN (2) AND YEAR(#Today) % 4 = 0 THEN 'Last ' + CAST(29 - day(#today) as varchar(255))
WHEN day(#today) >= 20 AND MONTH(#Today) IN (2) AND YEAR(#Today) % 4 <> 0 THEN 'Last ' + CAST(29 - day(#today) as varchar(255))
ELSE CAST(day(#today) as varchar(255))
END) + ' DAYS of ' + LEFT(DATENAME(month, #Today), 3) as Comments
DECLARE #Today DATE = '2016-11-09'
Select (CASE WHEN day(#today) <= 10 THEN 'First ' + DATENAME(day, #today)
WHEN day(#today) >= 20 THEN 'Last ' + CAST(DAY(DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,#Today)+1,0))) - day(#today) as varchar(255))
ELSE CAST(day(#today) as varchar(255) )
END) + ' DAYS of ' + LEFT(DATENAME(month, #Today), 3)
With SQL Server 2012 developers can now use new SQL date function EOMonth() for calculating the last date of the month where a given date is in.
Here is my query
--DECLARE #Today DATE = '2016-11-05'
DECLARE #Today DATE = '2016-11-24'
SELECT
case when DATEPART(dd,#Today) <= 10 then
'First ' + convert(varchar(2), DATEPART(dd,#Today)) + ' of ' + DATENAME(mm,#Today)
else
'Last ' + convert(varchar(2), DATEDIFF(dd, #Today, EOMONTH (#Today))) + ' of ' + DATENAME(mm,#Today)
end
The SQL EOMonth() function makes it easier to calculate the last date of a month, and also indirectly calculating the first date of next month or previous month
SELECT case when DATEPART(dd,#Today) <= 10 then
'First ' + convert(varchar(2), DATEPART(dd,#Today)) + ' DAYS of ' + DATENAME(mm,#Today)
WHEN DATEPART(dd,#Today) >= 20 then 'Last ' + convert(varchar(2),
DATEDIFF(dd, #Today, EOMONTH (#Today))) + ' DAYS of ' + DATENAME(mm,#Today)
ELSE #Today END
I have a query where I am pulling in three fields, and converting them to a date. I'm hoping to then run a comparison within the same select statement, but I get an invalid column name on the field I'm attempting to compare. The order by is working correctly though. /scratching_head
SQL Server 2012
SELECT
UTCSID,
UTLCID,
/* put utonmm, utondd, utonyy together as a date called uton */
CAST(
CAST(UTONMM as varchar) + '/' +
CAST(UTONDD as varchar) + '/' +
CASE WHEN UTONCV = '1'
THEN RIGHT('20' + CONVERT(varchar(4), RIGHT('00' + CONVERT(varchar(4), UTONYY),2)),4)
ELSE RIGHT('19' + CONVERT(varchar(4), UTONYY),4)
END
AS DATETIME) AS UTON,
/* put utofmm, utofdd, utofyy together as a date called utoff */
CAST(
CASE WHEN UTOFMM > '0'
THEN
CAST(UTOFMM as varchar) + '/' +
CAST(UTOFDD as varchar) + '/' +
CASE WHEN UTOFCV = '1'
THEN RIGHT('20' + CONVERT(varchar(4), RIGHT('00' + CONVERT(varchar(4), UTOFYY),2)),4)
ELSE RIGHT('19' + CONVERT(varchar(4), UTOFYY),4)
END
END
AS DATETIME) AS UTOFF,
UTCBAL,
UTDBAL,
UTUNPS
FROM [HTEDTA].[THOR].[HTEDTA].UT210AP
WHERE UTLCID = '885570' AND UTOFF > GETDATE() ORDER BY UTON DESC
This statement returns:
Invalid column name: 'UTOFF'
The problem is that the alias utoff isn't known at the time when the where clause is parsed.
One way to get around it is to wrap the query in a common table expression and apply the where clause to that:
WITH CTE AS (
SELECT UTCSID, UTLCID,
/* put utonmm, utondd, utonyy together as a date called uton */
CAST(
CAST(UTONMM as varchar) + '/' +
CAST(UTONDD as varchar) + '/' +
CASE WHEN UTONCV = '1'
THEN RIGHT('20' + CONVERT(varchar(4), RIGHT('00' + CONVERT(varchar(4), UTONYY),2)),4)
ELSE RIGHT('19' + CONVERT(varchar(4), UTONYY),4)
END
AS DATETIME) AS UTON,
/* put utofmm, utofdd, utofyy together as a date called utoff */
CAST(
CASE WHEN UTOFMM > '0'
THEN
CAST(UTOFMM as varchar) + '/' +
CAST(UTOFDD as varchar) + '/' +
CASE WHEN UTOFCV = '1'
THEN RIGHT('20' + CONVERT(varchar(4), RIGHT('00' + CONVERT(varchar(4), UTOFYY),2)),4)
ELSE RIGHT('19' + CONVERT(varchar(4), UTOFYY),4)
END
END
AS DATETIME) AS UTOFF,
UTCBAL, UTDBAL, UTUNPS
FROM [HTEDTA].[THOR].[HTEDTA].UT210AP
)
SELECT *
FROM CTE
WHERE UTLCID = '885570' AND UTOFF > GETDATE()
Hi I am having a hard time combining two records (from a single table) on a single query. The idea is, DATE_FIELD column is a date type and ColA is an integer data type.
To further illustrate my inquiry, I have attached an image below
1.) Is the raw table.
2.) Is the desired output.
P.S. The filter for DATE_FIELD is not a simple "WHERE DATE_FIELD IN" clause.
For example, I wanted to get the DATE_FIELD=12/30/2013. Then I need to get the Previous Sept DATE_FIELD also, which is 9/30/2013 programatically by using this query that I got from the web:
CASE
WHEN MONTH(DATE_FIELD) < 10
THEN
(cast(CAST((DATE_FIELD) - 1) as char(4)) + RIGHT('00' + LTRIM(09),2) + RIGHT('00' + LTRIM(30),2) AS Date))
ELSE
( cast(CAST((YEAR(DATE_FIELD)) as char(4)) + RIGHT('00' + LTRIM(09),2) + RIGHT('00' + LTRIM(30),2) AS Date))
END
Here is my current sql script (which cannot get the ColA equivalent for Previous Sept filter:
SELECT DATE_FIELD, ColA,
CASE
WHEN MONTH(DATE_FIELD) < 10
THEN
(cast(CAST((YEAR(DATE_FIELD) - 1) as char(4)) + RIGHT('00' + LTRIM(09),2) + RIGHT('00' + LTRIM(30),2) AS Date))
ELSE
( cast(CAST((YEAR(DATE_FIELD)) as char(4)) + RIGHT('00' + LTRIM(09),2) + RIGHT('00' + LTRIM(30),2) AS Date))
END AS PREVIOUS,
(
SELECT ColA
FROM TABLE_A
WHERE DATE_FIELD =
CASE
WHEN MONTH(DATE_FIELD) < 10
THEN
(cast(CAST((YEAR(DATE_FIELD) - 1) as char(4)) + RIGHT('00' + LTRIM(09),2) + RIGHT('00' + LTRIM(30),2) AS Date))
ELSE
( cast(CAST((YEAR(DATE_FIELD)) as char(4)) + RIGHT('00' + LTRIM(09),2) + RIGHT('00' + LTRIM(30),2) AS Date))
END
) AS PYE_colA
FROM TABLE_A
WHERE DATE_FIELD = '12/30/2013'
Thanks!
Do a cross join with the same table and use your CASE structure only in the where clause:
SELECT a.DATE_FIELD AS DATE_FIELD_1,
a.ColA AS ColA_1,
b.DATE_FIELD AS DATE_FIELD_2,
b.ColA AS ColA_2
FROM TABLE_A a
CROSS JOIN TABLE_A b
WHERE DATE_FIELD_1 = 'your date'
AND DATE_FIELD_2 = (
CASE
WHEN MONTH(DATE_FIELD_1) < 10
THEN
(cast(CAST((YEAR(DATE_FIELD_1) - 1) as char(4)) + RIGHT('00' + LTRIM(09),2) + RIGHT('00' + LTRIM(30),2) AS Date))
ELSE
( cast(CAST((YEAR(DATE_FIELD_1)) as char(4)) + RIGHT('00' + LTRIM(09),2) + RIGHT('00' + LTRIM(30),2) AS Date))
END)
;
Another possibility based on Thorsten Kettners remarks:
SELECT a.DATE_FIELD AS DATE_FIELD_1,
a.ColA AS ColA_1,
b.DATE_FIELD AS DATE_FIELD_2,
b.ColA AS ColA_2
FROM TABLE_A a
INNER JOIN TABLE_A b
ON b.DATE_FIELD = (
CASE
WHEN MONTH(a.DATE_FIELD) < 10
THEN
(cast(CAST((YEAR(a.DATE_FIELD) - 1) as char(4)) + RIGHT('00' + LTRIM(09),2) + RIGHT('00' + LTRIM(30),2) AS Date))
ELSE
( cast(CAST((YEAR(a.DATE_FIELD)) as char(4)) + RIGHT('00' + LTRIM(09),2) + RIGHT('00' + LTRIM(30),2) AS Date))
END)
WHERE a.DATE_FIELD = 'your date'
;
I have an app that allows users schedule an action to occur in the future. For example, that can select a date and schedule it to run on that day every month (ex: the 15th of each month). However, I now need to allow them to select a week day and week of the month. For example, they need to run an action the first friday of the month. Therefore I am allowing the to select the weekday (monday, tuesday, wednesday....) and week of the month (1st, 2nd, 3rd, 4th or 5th).
Here is the query I currently use:
Declare #nowString varchar(19)
Declare #nowDateString varchar(19)
Declare #now datetime
Declare #lastMinute datetime
Declare #nowDate datetime
Set #nowString = '#currentDateTime#:00'
Set #nowDateString = LEFT(#nowString, 10)
set #now = #nowString
set #nowDate = DATEADD(dd, 0, DATEDIFF(dd, 0, #now))
set #lastMinute = DATEADD(mi, -1, #now)
select *
from message_prepared
where schedule = '1'
and active = '1'
and noaa = '0'
and (
(
schedule_type = 'recurring'
and startdate <= #nowDate
and isnull(enddate, DATEADD(yy, 1, #nowDate)) >= #nowDate
and (
#nowDateString + ' ' + isnull(recurring_start_time_hour, '00') + ':' + isnull(recurring_start_time_min, '00') + ':00' = #now
or #nowDateString + ' ' + isnull(recurring_start_time_hour, '00') + ':' + isnull(recurring_start_time_min, '00') + ':00' = #lastMinute
)
-- Test for different type of recurring
and (
( ltrim(rtrim(recurring)) = 'M' and DATEPART(dd, startdate) = DATEPART(dd, #now) )
or ( ltrim(rtrim(recurring)) = 'W' and DATEPART(dw, startdate) = DATEPART(dw, #now) )
or ltrim(rtrim(recurring)) = 'D'
)
)
or (
schedule_type = 'once'
and startdate = #nowDate
and (
#nowDateString + ' ' + onetime_start_time_hour + ':' + onetime_start_time_min + ':00' = #now
or #nowDateString + ' ' + onetime_start_time_hour + ':' + onetime_start_time_min + ':00' = #lastMinute
)
)
)
and repeat_multiple_times = 0
UNION ALL
SELECT *
FROM MESSAGE_PREPARED
WHERE schedule = '1'
AND active = 1
AND noaa = 0
AND recurring = 'D'
AND repeat_multiple_times = 1
AND startDate IS NOT NULL
AND recurring_start_time_hour IS NOT NULL
AND recurring_start_time_hour < 24
AND recurring_start_time_min IS NOT NULL
AND recurring_start_time_min < 60
AND startdate <= #nowDate
AND ISNULL(enddate, DATEADD(yy, 1, #nowDate)) >= #nowDate
AND
(
CASE WHEN repeat_unit = 'M'
THEN
DATEDIFF(n,
CONVERT(DATETIME,
CAST(DATEPART(yyyy, startDate) AS VARCHAR(4)) + '-' +
CAST(DATEPART(mm, startDate) AS VARCHAR(2)) + '-' +
CAST(DATEPART(dd, startDate) AS VARCHAR(2)) + ' ' +
CAST(recurring_start_time_hour AS VARCHAR(2)) + ':' +
CAST(recurring_start_time_min AS VARCHAR(2)) + ':00', 20),
GETDATE()) % repeat_interval
ELSE
DATEDIFF(n,
CONVERT(DATETIME,
CAST(DATEPART(yyyy, startDate) AS VARCHAR(4)) + '-' +
CAST(DATEPART(mm, startDate) AS VARCHAR(2)) + '-' +
CAST(DATEPART(dd, startDate) AS VARCHAR(2)) + ' ' +
CAST(recurring_start_time_hour AS VARCHAR(2)) + ':' +
CAST(recurring_start_time_min AS VARCHAR(2)) + ':00', 20),
GETDATE()) % (repeat_interval * 60)
END = 0
OR
CASE WHEN repeat_unit = 'M'
THEN
(DATEDIFF(n,
CONVERT(DATETIME,
CAST(DATEPART(yyyy, startDate) AS VARCHAR(4)) + '-' +
CAST(DATEPART(mm, startDate) AS VARCHAR(2)) + '-' +
CAST(DATEPART(dd, startDate) AS VARCHAR(2)) + ' ' +
CAST(recurring_start_time_hour AS VARCHAR(2)) + ':' +
CAST(recurring_start_time_min AS VARCHAR(2)) + ':00', 20),
GETDATE()) - 1) % repeat_interval
ELSE
(DATEDIFF(n,
CONVERT(DATETIME,
CAST(DATEPART(yyyy, startDate) AS VARCHAR(4)) + '-' +
CAST(DATEPART(mm, startDate) AS VARCHAR(2)) + '-' +
CAST(DATEPART(dd, startDate) AS VARCHAR(2)) + ' ' +
CAST(recurring_start_time_hour AS VARCHAR(2)) + ':' +
CAST(recurring_start_time_min AS VARCHAR(2)) + ':00', 20),
GETDATE()) - 1) % (repeat_interval * 60)
END = 0
)
This will only occur when reocurring is set to "M" and I would like to determine if today is the specific day of the week, week of the month and hour/min.
This is pretty simple logic. Today is the nth DOW of the month when the following is true:
Today is that day of the week
The day of the month is between 7*(n-1) + 1 and 7 * n
So, the first Monday of the month is always between the 1st and 7th, and so on. Here is an example case statement to test this:
declare #DayOfWeek varchar(255) = 'Thursday';
declare #Which int = 3;
select (case when datename(dw, Today) = #DayOfWeek and
(DAY(Today) - 1) / 7 = #Which - 1
then 1
else 0
end)
from (select CAST(getdate() as date) as Today) t
I've structured the query this way so you can test it with different values. Just replace the expression that defines Today, with something like getdate() - 3 or '2013-01-01'.