Please start any new threads on our new
site at https://forums.sqlteam.com. We've got lots of great SQL Server
experts to answer whatever question you can come up with.
| Author |
Topic |
|
Autofreak
Starting Member
9 Posts |
Posted - 2011-01-18 : 17:45:28
|
| Hello, I have the following problem.Table: TestFields:Number intNumberDifference intNumberDate Datethe table has fields Number and NumberDate filled. NumberDate column has data values for each day in the calender including weekends. NumberDifference is empty. We need to populatethe NumberDifference field with the values that are equal the difference between the values of the Number field for the current NumberDate and the previous NumberDate.ex:Initial table valuesNumber | NumberDifference | NumberDate1 | | 01/01/20115 | | 01/02/201112 | | 01/03/201115 | | 01/04/2011table after the procedure is executedNumber | NumberDifference | NumberDate1 | 1 | 01/01/20115 | 4 | 01/02/201112 | 7 | 01/03/201115 | 3 | 01/04/2011I would like to accomplish this task without using cursors or temporary tables.Thanks a lot. |
|
|
robvolk
Most Valuable Yak
15732 Posts |
Posted - 2011-01-18 : 18:29:44
|
I got this to work:;WITH n(Number,NumberDiff, ROW) AS (SELECT Number, NumberDifference, ROW_NUMBER() OVER (ORDER BY Number) FROM Test)UPDATE b SET NumberDiff=b.Number-a.NumberFROM n a INNER JOIN n b ON a.row=b.row-1UPDATE Test SET NumberDifference=1 WHERE NumberDifference IS NULL |
 |
|
|
jcelko
Esteemed SQL Purist
547 Posts |
Posted - 2011-01-18 : 18:38:47
|
| Please post DDL, so that people do not have to guess what the keys, constraINTEGER NOT NULL,s, Declarative Referential INTEGER NOT NULL,egrity, data types, etc. in your schema are. If you know how, follow ISO-11179 data element naming conventions and formatting rules. Temporal data should use ISO-8601 formats. Code should be in Standard SQL as much as possible and not local dialect. It would also help if you knew the differences between rows and records, fields and columns. The Delta is a computed column, so why store it? CREATE TABLE Test(test_date DATE NOT NULL PRIMARY KEY, test_score INTEGER);>> the table has fields [sic] test_score and test_date filled. The test_date column has data values for each day in the calender including weekends. The test_delta is empty [sic: NULL, empty is not a numeric value]. <<Here is the syntax for table insertion:INSERT INTO TestsVALUES (1, '2011- 01-01'), -- ISO-8601 date formats, please(5, '2011- 01-02'),(12, '2011- 01-03'),(15, '2011- 01-04');Use a VIEW that will always be correct and not need updating when something changes. CREATE VIEW Test_Deltas ( test_date,test_score, test_delta)AS SELECT T1.test_date, T1.test_score, (T2.test_score - T1.test_score) AS test_delta FROM Tests AS T1, Tests AS T2WHERE T1.test_date = DATEADD(DAY, -1, T2.test_date);--CELKO--Books in Celko Series for Morgan-Kaufmann PublishingAnalytics and OLAP in SQLData and Databases: Concepts in Practice Data, Measurements and Standards in SQLSQL for SmartiesSQL Programming Style SQL Puzzles and Answers Thinking in SetsTrees and Hierarchies in SQL |
 |
|
|
Autofreak
Starting Member
9 Posts |
Posted - 2011-01-19 : 15:56:10
|
quote: Originally posted by robvolk I got this to work:;WITH n(Number,NumberDiff, ROW) AS (SELECT Number, NumberDifference, ROW_NUMBER() OVER (ORDER BY Number) FROM Test)UPDATE b SET NumberDiff=b.Number-a.NumberFROM n a INNER JOIN n b ON a.row=b.row-1UPDATE Test SET NumberDifference=1 WHERE NumberDifference IS NULL
quote: Thank you, it works very well. Could you please provide some explanation as well?
|
 |
|
|
robvolk
Most Valuable Yak
15732 Posts |
Posted - 2011-01-19 : 16:00:48
|
| I used a common table expression (CTE) to add a sequential row number to the results. I then joined the CTE back to itself, offsetting the row number by 1, to do the UPDATE. The 2nd UPDATE catches the first row that doesn't have a previous row.CTEs and ROW_NUMBER() are documented in SQL Server Books Online if you want more information about them. |
 |
|
|
Autofreak
Starting Member
9 Posts |
Posted - 2011-01-19 : 16:07:27
|
quote: Originally posted by jcelko Please post DDL, so that people do not have to guess what the keys, constraINTEGER NOT NULL,s, Declarative Referential INTEGER NOT NULL,egrity, data types, etc. in your schema are. If you know how, follow ISO-11179 data element naming conventions and formatting rules. Temporal data should use ISO-8601 formats. Code should be in Standard SQL as much as possible and not local dialect. It would also help if you knew the differences between rows and records, fields and columns. The Delta is a computed column, so why store it? CREATE TABLE Test(test_date DATE NOT NULL PRIMARY KEY, test_score INTEGER);>> the table has fields [sic] test_score and test_date filled. The test_date column has data values for each day in the calender including weekends. The test_delta is empty [sic: NULL, empty is not a numeric value]. <<Here is the syntax for table insertion:INSERT INTO TestsVALUES (1, '2011- 01-01'), -- ISO-8601 date formats, please(5, '2011- 01-02'),(12, '2011- 01-03'),(15, '2011- 01-04');Use a VIEW that will always be correct and not need updating when something changes. CREATE VIEW Test_Deltas ( test_date,test_score, test_delta)AS SELECT T1.test_date, T1.test_score, (T2.test_score - T1.test_score) AS test_delta FROM Tests AS T1, Tests AS T2WHERE T1.test_date = DATEADD(DAY, -1, T2.test_date);--CELKO--Books in Celko Series for Morgan-Kaufmann PublishingAnalytics and OLAP in SQLData and Databases: Concepts in Practice Data, Measurements and Standards in SQLSQL for SmartiesSQL Programming Style SQL Puzzles and Answers Thinking in SetsTrees and Hierarchies in SQL
quote: thank you for the solution and comments. They don't provide the solution requested though. Please read it carefully.
|
 |
|
|
Autofreak
Starting Member
9 Posts |
Posted - 2011-02-05 : 19:41:08
|
quote: Originally posted by robvolk I used a common table expression (CTE) to add a sequential row number to the results. I then joined the CTE back to itself, offsetting the row number by 1, to do the UPDATE. The 2nd UPDATE catches the first row that doesn't have a previous row.CTEs and ROW_NUMBER() are documented in SQL Server Books Online if you want more information about them.
quote: great, thank you much. Miraculously, i had similar question on an interview
|
 |
|
|
|
|
|
|
|