Query to compare cast in select statement - sql

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()

Related

Calculate and Display Total Experience Months in YY/MM format in Sql Server

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

Combining two rows in one select query

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'
;

Concatenating two TIME columns in SQL Server 2012

I want to concatenate two TIME columns and show as one column.
Example:
FromTime: 9:00
ToTime: 12:00
Result should be:
9:00-12:00
Generic SQL:
-- hh:mm:ss
SELECT 'result:' + CONVERT(CHAR(6), FromTime, 8) + '-' + CONVERT(CHAR(6), ToTime)
FROM yourTable
MySQL:
-- hh:mm
SELECT 'result:' + DATE_FORMAT(FromTime, '%H:%i') + '-' + DATE_FORMAT(ToTime, '%H:%i')
FROM yourTable
SQL Server:
-- hh:mm
SELECT 'result:' + convert(char(2), DATEPART(hh, FromTime)) + ':' +
CONVERT(CHAR(2), DATEPART(mm, FromTime)) + '-' +
CONVERT(CHAR(2), DATEPART(hh, ToTime)) + ':' +
CONVERT(CHAR(2), DATEPART(mm, ToTime))
FROM yourTable
declare #FromTime time
declare #ToTime time
set #FromTime='9:00'
set #ToTime='12:00'
select cast(#FromTime as varchar(10))+ '-' + cast(#ToTime as varchar(10)) as result
sql demo
You can use convert
select convert(VARCHAR(5),getdate(),108) + ' - ' + convert(VARCHAR(5),getdate()-1,108)

Using DatePart in line of a larger sql clause

This statement will correctly merge 2 columns ('DATE' and 'TIME'):
update AllBW1 set sUserTime =
CAST(
(
STR( YEAR( [DATE] ) ) + '/' +
STR( MONTH( [DATE] ) ) + '/' +
STR( DAY( [DATE] ) ) + ' ' +
(select DATENAME(hour, [TIME]))+ ':' +
(select DATENAME(minute, [TIME])) + ':' +
(select DATENAME(SECOND, [TIME]))
) as DATETIME)
where sUserTime is null
I'd like to refine the above so as to replace the default timezone with my own (GMT-6).
I've tried a few variations:
CAST((select DATEADD(hour, -6, DATENAME(hour, [TIME]))) as smalldatetime) + ':' +
and
(select CAST(DATEADD(hour, -6, DATENAME(hour, [TIME]))) as datetime) + ':' +
and have achieved no joy.
thx
The logfile as parsed into the SQL table by LogParser 2.2 has separate fields for Date and Time but, since both are formatted as datatime fields they end up looking like:
2012-01-04 00:00:00.000 for date (all time fields are zeroed)
2012-01-01 06:04:41.000 for time (all date field = first day of current year)
That's the reason the query is parsing each element the way it is. Thanks to Dems comment I simplified everything down. I've no doubt this can be optimized by for the volumes I'm dealing with this is adaquate:
update myTable set sUserTime =
(
DATENAME(YEAR, [DATE] ) + '/' +
DATENAME(MONTH, [DATE] ) + '/' +
DATENAME(DAY, [DATE] ) + ' ' +
DATENAME(hour, (dateadd(hh, -6, [time])))+ ':' +
DATENAME(minute, [TIME]) + ':' +
DATENAME(SECOND, [TIME])
)
where sUserTime is null

How to convert date into DD-MON-YYYY HH24:MI:SS format?

Can someone help me with SQL Date format?
The following statement
SELECT convert(VARCHAR(20),GETDATE(),113)
returns
04 Aug 2011 08:08:08.
I want the results like
Aug-04-2011 08:08:08
Thank you!
SELECT
LEFT(DATENAME(MONTH, Date), 3) + '-' +
RIGHT(100 + DAY(Date), 2) + '-' +
DATENAME(YEAR, Date) + ' ' +
CONVERT(varchar, Date, 108)
FROM (SELECT Date = GETDATE()) s
Off the top of my head, I think its:
SELECT convert(VARCHAR(20),GETDATE(),120)
EDIT:
This will work:
SELECT datename(day, GETDATE()) + '-'
+ substring(datename(month, GETDATE()),0,4) + '-'
+ datename(year, GETDATE()) + ' '
+ datename(hh, GETDATE()) + ':'
+ datename(mi, GETDATE()) + ':'
+ datename(ss, GETDATE())
SECOND EDIT:
SELECT substring(datename(month, GETDATE()),0,4) + '-'
+ datename(day, GETDATE()) + '-'
+ datename(year, GETDATE()) + ' '
+ datename(hh, GETDATE()) + ':'
+ datename(mi, GETDATE()) + ':'
+ datename(ss, GETDATE())
THIRD EDIT:
select substring(datename(month, GETDATE()),0,4) + '-'
+ right(datename(day, GETDATE())+100,2) + '-'
+ datename(year, GETDATE()) + ' '
+ right(datename(hh, GETDATE())+100,2) + ':'
+ right(datename(mi, GETDATE())+100,2) + ':'
+ right(datename(ss, GETDATE())+100,2)
The built-in convert won't allow you to format your date exactly as you desire, unfortunately.
With a little manipulation, you can get there though:
SELECT stuff(stuff(convert(VARCHAR(20),GETDATE(),113), 3, 1, '-'), 7, 1, '-')
You could put this in a UDF and call that whenever you want your date formatted in this manner.