T-SQL 2012: Embedding a Calculated field within a Select Statement with a Variable
-
Monday, January 07, 2013 1:14 AM
Problem: I'm trying to check DB1.Date1 to see if the current record is the most current date of all the records. If the current record is the most current date I want to store the value "Current" in a new column called "TransStatus". If the DB1.Date1 is not the most current date store "Prior" in DB1.TransStatus.
I don't know how to write this and realize the following code is bugus, but hopefully it explains what I'm trying to do.
I'm new to SQL Variables and Calculated fields.
Thank you.
Bob Sutor
CODE LOGIC:
Declare @Status CHAR(7) = ' '
Select
DB1.Date1,
IF DB1.Date = max(DB1.Date1) then @Status = "Current" Else @Status = "Prior"
DB1.TransStatus = @Status
DB1.EmployeeName
From: DB1
All Replies
-
Monday, January 07, 2013 1:41 AMModerator
select Db1.Date1, case when row_number() over (order by Db1.Date1 DESC) = 1 then 'Current' else 'Prior' end as [Status], Db1.EmployeeName
from Db1
or
;with cte as (select *, row_number() over (order by Date1 DESC) as Rn from Db1) select *, case when Rn=1 then 'Current' else 'Prior' end as [Status] from cte
For every expert, there is an equal and opposite expert. - Becker's Law
My blog- Edited by Naomi NMicrosoft Community Contributor, Moderator Monday, January 07, 2013 1:43 AM
-
Monday, January 07, 2013 2:40 AM
Please post DDL, so that people do not have to guess what the keys, constraints, Declarative Referential Integrity, data types, etc. in your schema are. Learn to follow ISO-11179 data element naming conventions and formatting rules (you did not, but were close). Temporal data should use ISO-8601 formats. Code should be in Standard SQL as much as possible and not local dialect.
This is minimal polite behavior on SQL forums.
Sample data is also a good idea, along with clear specifications. It is very hard to debug code when you do not let us see it.
Date is a reserved word, as well as too vague to be a data element name. Rows are not anything like records, columns are not fields.
>> I'm trying to check DB1. to see if the current record [sic] is the most current date of all the records [sic]. If the current record [sic] is the most current date I want to store the value "Current" in a new column called "trans_status". If the DB1.foobar_date is not the most current date store "Prior" in DB1.trans_status. <<
We do not materialize computed values like we did in the fields of records in files. Create a VIEW that is always right:
SELECT X.employee_name, X.foobar_date, ..,
CASE WHEN X.foobar_date = X.current_foobar_date
THEN 'Current' ELSE 'Prior' END
AS foobar_status
FROM (SELECT employee_name, foobar_date, ..,
MAX(foobar_date) OVER () AS current_foobar_date
FROM Floobs)
AS X;--CELKO-- Books in Celko Series for Morgan-Kaufmann Publishing: Analytics and OLAP in SQL / Data and Databases: Concepts in Practice Data / Measurements and Standards in SQL SQL for Smarties / SQL Programming Style / SQL Puzzles and Answers / Thinking in Sets / Trees and Hierarchies in SQL
- Proposed As Answer by Naomi NMicrosoft Community Contributor, Moderator Monday, January 07, 2013 4:11 AM
- Marked As Answer by Allen Li - MSFTModerator Monday, January 14, 2013 6:12 AM
-
Monday, January 07, 2013 3:02 AM
Hi Naomi!
I"m not sure I understand the "When Row_Number() Over" is doing. I know what the (Order by Db1.Date1 DESC) = 1 is?? Also I'm actually trying the determine the latest date for each given Employee. Each employee has mulitiple records in the table (Employee-Sequence). I assume a Max(Db1.Date1) could not be used?? Could a Group By Clause be used? Also how would I test for a Null condition in a Case statement? Sorry I only gave you a part of the problem.
Select Db1.Date1 (I want to show this value separately)
Case Db1.Date1
WHEN rownumber() over (orderby Db1.Date1 DESC) =1 THEN 'Current'
END AS Status
Db1.EmployeeName,
Db1.Sequence
FROM Db1
-
Monday, January 07, 2013 4:10 AMModerator
If you want the latest date per employee, we just need to add partition by, e.g.
;with cte as (select *, row_number() over (partition by EmployeeId order by Date1 DESC) as Rn from Db1) select *, case when Rn=1 then 'Current' else 'Prior' end as [Status] from cte
To understand my suggestion you may find the following blogs useful
Optimizing TOP N per Group Queries - blog by Itzik Ben-Gan explaining various optimization ideas
Including an Aggregated Column's Related Values - Erik and mine blog presenting several solutions of the problem with explanations for each
Including an Aggregated Column's Related Values - Part 2 - my blog post with use cases for the previous blogFor every expert, there is an equal and opposite expert. - Becker's Law
My blog- Marked As Answer by Allen Li - MSFTModerator Monday, January 14, 2013 6:12 AM

