|
Archives of the TeradataForumMessage Posted: Fri, 16 Dec 2005 @ 11:14:10 GMT
Hi all, I have a table that has (amongst its 15 fields) an Id, a Year and a Status Code. For each Id, there are multiple years, with different status codes. The table is very large (over 208 million records). In the past, I have used either of the following syntax to collate the data for each Id into a single row: Option One ========== SELECT Id ,CASE SUM( CASE WHEN Yr = 1997 AND Rtn_Sts_Cd = 'A' THEN 1 WHEN Yr = 1997 AND Rtn_Sts_Cd = 'B' THEN 2 WHEN Yr = 1997 AND Rtn_Sts_Cd = 'C' THEN 3 WHEN Yr = 1997 AND Rtn_Sts_Cd = 'D' THEN 4 (etc) ELSE 0 END ) WHEN 1 THEN 'A' WHEN 2 THEN 'B' WHEN 3 THEN 'C' WHEN 4 THEN 'D' (etc) END AS Sts_Cd_97 ,CASE SUM( CASE WHEN Yr = 1998 AND Rtn_Sts_Cd = 'A' THEN 1 WHEN Yr = 1998 AND Rtn_Sts_Cd = 'B' THEN 2 WHEN Yr = 1998 AND Rtn_Sts_Cd = 'C' THEN 3 WHEN Yr = 1998 AND Rtn_Sts_Cd = 'D' THEN 4 (etc) ELSE 0 END ) WHEN 1 THEN 'A' WHEN 2 THEN 'B' WHEN 3 THEN 'C' WHEN 4 THEN 'D' (etc) END AS Sts_Cd_98 ,(etc) FROM Role_Year GROUP BY Id ; OPTION 2 ======== SELECT t0.Id ,t1.Rtn_Sts_Cd AS Sts_Cd_97 ,t2.Rtn_Sts_Cd AS Sts_Cd_98 ,t3.Rtn_Sts_Cd AS Sts_Cd_99 ,t4.Rtn_Sts_Cd AS Sts_Cd_00 (etc) FROM Role_Year AS t0 LEFT OUTER JOIN Role_Year AS t1 ON t1.Id = t0.Id LEFT OUTER JOIN Role_Year AS t2 ON t2.Id = t0.Id (etc) WHERE t0.Yr = 1997 AND t1.Yr = 1998 AND t2.Yr = 1999 AND t3.Yr = 2000 AND t4.Yr = 2001 ; As you can see, both methods are quite cumbersome (keeping in mind that I have skipped over large portions of the repetitive code). I should point out that both of these bits of code work quite effectively, they just annoy me because they aren't "pretty". We upgraded to v2r6 on the weekend, and I have been playing around a little with Recursive Queries. I thought I could use this piece of code, setting the Sts_Cd to a default ' ', and then recursively producing a new record with the previous, and next Sts_Cd populated: WITH RECURSIVE MyYears ( Id ,Cycle_Year ,Sts_Cd_97 ,Sts_Cd_98 ,Sts_Cd_99 ,Sts_Cd_00 ,Sts_Cd_01 ,Sts_Cd_02 ,Sts_Cd_03 ,Sts_Cd_04 ) AS ( SELECT Id ,1997 ,Rtn_Sts_Cd ,' ' ,' ' ,' ' ,' ' ,' ' ,' ' ,' ' FROM Role_Year WHERE Yr = 1997 UNION ALL SELECT my.Id ,my.Cycle_Year + 1 ,my.Sts_Cd_97 ,CASE WHEN ry.Yr = my.Cycle_Year + 1 THEN Rtn_Sts_Cd ELSE my.Sts_Cd_98 END ,CASE WHEN ry.Yr = my.Cycle_Year + 1 THEN Rtn_Sts_Cd ELSE my.Sts_Cd_99 END ,CASE WHEN ry.Yr = my.Cycle_Year + 1 THEN Rtn_Sts_Cd ELSE my.Sts_Cd_00 END ,CASE WHEN ry.Yr = my.Cycle_Year + 1 THEN Rtn_Sts_Cd ELSE my.Sts_Cd_01 END ,CASE WHEN ry.Yr = my.Cycle_Year + 1 THEN Rtn_Sts_Cd ELSE my.Sts_Cd_02 END ,CASE WHEN ry.Yr = my.Cycle_Year + 1 THEN Rtn_Sts_Cd ELSE my.Sts_Cd_03 END ,CASE WHEN ry.Yr = my.Cycle_Year + 1 THEN Rtn_Sts_Cd ELSE my.Sts_Cd_04 END FROM MyYears AS my INNER JOIN pinc.Role_Year AS ry ON ry.Id = my.Id AND ry.Yr = my.Cycle_Year + 1 AND my.Cycle_Year < 2005 ) SELECT * FROM MyYears WHERE Cycle_Year = 2004 ORDER BY TFN ASC ; The problem I have is that the table size will increase exponentially (and quickly bring my system to a grinding halt) with each recursion that occurs. What I would ideally like to do is limit the FROM clause in the recursive select to: WHERE my.Cycle_Year IN ( SELECT MAX(Cycle_Year) FROM MyYears ) Obviously, I can't do that because I can't use either derived tables or aggregates in the recursive part of the query. I was curious as to whether anyone can suggest an alternative that would reduce the number of rows generated by the recursive query. A recursive update would be great, but I can't see how it would work. Andrew Young
| ||||||||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||||||||
Copyright 2016 - All Rights Reserved | ||||||||||||||||||||||||||||||||||||||||||||||||
Last Modified: 15 Jun 2023 | ||||||||||||||||||||||||||||||||||||||||||||||||