|
|
|
Forum Newbie
      
Group: General Forum Members
Last Login: Thursday, January 17, 2013 11:22 AM
Points: 1,
Visits: 27
|
|
Doing this in SQL 2008.
Is it possible to use the results of one column to calculate another column? Example:
Select .. VERY LONG FORMULA as Results1
I need another column with a CASE so..
CASE Result1 < 100 Then something as Results2
Is it possible to do something like this or do I have to do the whole long formula again like...
CASE VERY LONG FORMULA < 100 Then something as Result2
I already have Results1 and it's silly to do it again just to calculate Results2.
God I hope this isn't too confusing.
Thanks in advance. Phil
|
|
|
|
|
Old Hand
      
Group: General Forum Members
Last Login: Yesterday @ 8:59 AM
Points: 342,
Visits: 1,074
|
|
If you make one result as persistent calculated column, and other as non-persistent calculated column, than maybe. If you want to be sure, instead of calculated fields use trigger to calculate and store both values, but that may not be as performant. Other idea is to make result1 as persistent calculated field and then view on top of that table that has calculation for result2. Or, do it completely non-persistent, with view that has nested subquery or cross apply or cte that would guarantee the order of calculations and reusage of result from previous level. My favourite would be completely persistent solution, or cross apply from non-persistent world, depending on read-write ratio of that table and cost of formula calculation. Hth
_____________________________________________________ XDetails Addin - for SQL Developers and DBA blog.sqlxdetails.com - Transaction log myths - debunked!
|
|
|
|
|
SSCommitted
      
Group: General Forum Members
Last Login: Tuesday, January 15, 2013 11:11 AM
Points: 1,945,
Visits: 2,782
|
|
I already have Results1 and it's silly to do it again just to calculate Results2.
Here is how a SELECT works in SQL ... at least in theory. Real products will optimize things, but the code has to produce the same results.
a) Effectively materialize the CTEs in the optional WITH clause. CTE's come into existence in the order they are declared so only backward references are alllowed. A CTE can be recursive. Think of them as VIEWs that exist only in the scope of the query. In practice, if they are used once then they are implemented as an in-line macro.
b) Start in the FROM clause and build a working table from all of the joins, unions, intersections, and whatever other table constructors are there. The <table expression> AS <correlation name> option allows you give a name to this working table which you then have to use for the rest of the containing query. Ther are UNIONB, INTERSECT and EXCEPT set construtors, LATERAL tables, table-valued funcitosn and all kinds of things happening in here.
c) Go to the WHERE clause and remove rows that do not pass criteria; that is, that do not test to TRUE (i.e. reject UNKNOWN and FALSE). The WHERE clause is applied to the working set in the FROM clause.
d) Go to the optional GROUP BY clause, partiton the original table into groups and reduce each grouping to a *single* row, replacing the original working table with the new grouped table. The rows of a grouped table must be only group characteristics: (1) a grouping column (2) a statistic about the group (i.e. aggregate functions) (3) a function or constant(4) an expression made up of only those three items. The original table no longer exists and you cannot reference anything in it (this was an error in early Sybase products).
e) Go to the optional HAVING clause and apply it against the grouped working table; if there was no GROUP BY clause, treat the entire table as one group.
f) Go to the SELECT clause and construct the expressions in the list. This means that the scalar subqueries, function calls and expressions in the SELECT are done after all the other clauses are done. The AS operator can also give names to expressions in the SELECT list. These new names come into existence all at once, but after the WHERE clause, GROUP BY clause and HAVING clause have been executed; you cannot use them in the SELECT list or the WHERE clause for that reason.
If there is a SELECT DISTINCT, then redundant duplicate rows are removed. For purposes of defining a duplicate row, NULLs are treated as matching (just like in the GROUP BY).
g) Nested query expressions follow the usual scoping rules you would expect from a block structured language like C, Pascal, Algol, etc. Namely, the innermost queries can reference columns and tables in the queries in which they are contained.
h) The ORDER BY clause is part of a cursor, not a query. The result set is passed to the cursor, which can only see the names in the SELECT clause list, and the sorting is done there. The ORDER BY clause cannot have expression in it, or references to other columns because the result set has been converted into a sequential file structure and that is what is being sorted.
As you can see, things happen "all at once" in SQL, not "from left to right" as they would in a sequential file/procedural language model. In those languages, these two statements produce different results: READ (a, b, c) FROM File_X; READ (c, a, b) FROM File_X;
while these two statements return the same data:
SELECT a, b, c FROM Table_X; SELECT c, a, b FROM Table_X;
Think about what a confused mess this statement is in the SQL model.
SELECT f(c2) AS c1, f(c1) AS c2 FROM Foobar;
That is why such nonsense is illegal syntax.
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
|
|
|
|
|
Ten Centuries
      
Group: General Forum Members
Last Login: Monday, May 20, 2013 12:37 AM
Points: 1,049,
Visits: 1,439
|
|
I already have Results1 and it's silly to do it again just to calculate Results2.
I am assuming that Results1 is a data set that you are selecting a table. I agree with Joe on this one. You can user a CTE or a derived table to calcualte Results2 on the basis of Results1.
Here are a few links on how to use them:
Using Derived Tables
Using CTE
Hope this helps.
Vinu Vijayan
For better and faster solutions please check..."How to post data/code on a forum to get the best help" - Jeff Moden
|
|
|
|
|
SSC Eights!
      
Group: General Forum Members
Last Login: Today @ 2:20 AM
Points: 921,
Visits: 3,746
|
|
|
|
|
|
Forum Newbie
      
Group: General Forum Members
Last Login: Sunday, January 06, 2013 8:46 AM
Points: 1,
Visits: 12
|
|
if the resultset is not very big then the simplest way of doing is,
SELECT *, CASE Result1 < 100 Then something as Results2 FROM (Select .. VERY LONG FORMULA as Results1) t1
Raju
|
|
|
|
|
SSC-Dedicated
           
Group: General Forum Members
Last Login: Yesterday @ 7:51 PM
Points: 32,910,
Visits: 26,800
|
|
CELKO (1/4/2013) h) The ORDER BY clause is part of a cursor, not a query. The result set is passed to the cursor, which can only see the names in the SELECT clause list, and the sorting is done there. The ORDER BY clause cannot have expression in it, or references to other columns because the result set has been converted into a sequential file structure and that is what is being sorted.
Not that it's a particularly useful example of a sort but, just to prove how wrong virtually everything in the statement above can actually be in T-SQL, please consider the following...
SELECT service_broker_guid FROM sys.Databases ORDER BY CASE WHEN database_id < = 4 THEN N' ' + name ELSE CAST(create_date AS NVARCHAR(128)) END Note that nothing in the SELECT list is referenced by the ORDER BY, that the ORDER BY does, in fact have several expressions in it and is really just one big expression to begin with, and that it not only references columns outside the SELECT list but conditionally sorts based on the content of two entirely different columns.
CELKO (1/4/2013) a) Effectively materialize the CTEs in the optional WITH clause. CTE's come into existence in the order they are declared so only backward references are alllowed.
{snip}
As you can see, things happen "all at once" in SQL, not "from left to right" as they would in a sequential file/procedural language model.
As you can see in your own writing, "It Depends". Some things don't actually happen "all at once" in SQL. In fact, even an update on a single column doesn't happen all at once. It happens just like procedural code... one row at a time, one page at a time.
--Jeff Moden "RBAR is pronounced "ree-bar" and is a "Modenism" for "Row-By-Agonizing-Row".
First step towards the paradigm shift of writing Set Based code: Stop thinking about what you want to do to a row... think, instead, of what you want to do to a column."
For better, quicker answers on T-SQL questions, click on the following... http://www.sqlservercentral.com/articles/Best+Practices/61537/
For better answers on performance questions, click on the following... http://www.sqlservercentral.com/articles/SQLServerCentral/66909/
|
|
|
|
|
SSC-Dedicated
           
Group: General Forum Members
Last Login: Yesterday @ 7:51 PM
Points: 32,910,
Visits: 26,800
|
|
|
|
|
|
Ten Centuries
      
Group: General Forum Members
Last Login: 2 days ago @ 3:56 PM
Points: 1,324,
Visits: 1,778
|
|
If all the columns are from a single table, you definitely should created a computed column that has the computation: that way, the definition is in only one place. You do not have to persist it, although you could -- you can base that on how often you use it vs how much overhead it really is to calculate vs the bytes needed to store it.
Whether persisted or not, you can use it in a SELECT just like any other column. For example:
ALTER TABLE dbo.yourtablename ADD Results1 AS Col1 * 1.57 / Col2 * CASE WHEN Col3 = 'A' THEN Col4 ELSE Col5 END
Then your query can be:
SELECT Results1, Colx / Results1 AS ... FROM dbo.yourtablename WHERE Results1 >= 9.75 GROUP BY Results1 ORDER BY Results1
SQL DBA,SQL Server MVP('07, '08, '09) One man with courage makes a majority. Andrew Jackson
|
|
|
|
|
Ten Centuries
      
Group: General Forum Members
Last Login: 2 days ago @ 3:56 PM
Points: 1,324,
Visits: 1,778
|
|
CELKO (1/4/2013) Think about what a confused mess this statement is in the SQL model.
SELECT f(c2) AS c1, f(c1) AS c2 FROM Foobar;
That is why such nonsense is illegal syntax.
Your claim is nonsense. I don't see what's illegal about that general syntax in SQL Server, viz:
SELECT RTRIM(c2) AS c1, RTRIM(c1) AS c2 FROM ( SELECT 'Y' AS c1, 'Z' AS c2 UNION ALL SELECT 'C' AS c1, 'D' AS c2 UNION ALL SELECT 'A' AS c1, 'B' AS c2 ) AS test_data ORDER BY c1
SQL DBA,SQL Server MVP('07, '08, '09) One man with courage makes a majority. Andrew Jackson
|
|
|
|