Author |
Topic |
madlo
Starting Member
41 Posts |
Posted - 2015-03-09 : 08:30:34
|
i have the following dataTableTAcc no, T1Total,T2Total,T3Total1,10,10,102,20,20,203,30,30,30TableAAcc no, A1Total,A2Total,A3Total1,40,40,407,50,50,408,60,60,60I want the desired output to beTableOutputAcc no, T1Total,T2Total,T3Total, A1Total,A2Total,A3Total1,10,10,10,0,0,02,20,20,20,0,0,03,30,30,30,0,0,01,0,0,0,40,40,407,0,00,50,50,508,0,0,0,60,60,60Simple enough just use a UNION SELECT Acc no, 0,0,0,A1Total,A2Total,A3TotalUNION ALLSELECT Acc no, T1Total,T2Total,T3Total,0,0,0However my solution was simplistic but I have many tables with many columns and I don't always want to put placeholder values columns in it. (nulls instead of zeros is also fine)So I wold rather want to do something that just allows me to do something like this. SELECT Acc no, A1Total,A2Total,A3TotalFANCY UNIONSELECT Acc no, T1Total,T2Total,T3Totaland it will now to return the output as Acc no, A1Total,A2Total,A3Total,T1Total,T2Total,T3Total |
|
gbritton
Master Smack Fu Yak Hacker
2780 Posts |
Posted - 2015-03-09 : 13:30:32
|
Your FANCY UNION is called a JOIN |
|
|
madlo
Starting Member
41 Posts |
Posted - 2015-03-13 : 03:41:06
|
quote: Originally posted by gbritton Your FANCY UNION is called a JOIN
Not sure where my mind went.I don't want to join the acc no. From my example the output should include two lines for acc 11,10,10,10,0,0,01,0,0,0,40,40,40You are correct then the solution is a JOIN.Here is the querySELECT ISNULL(TableT.Acc,TableA.Acc) ,A1Total,A2Total,A3Total,T1Total,T2Total,T3TotalFROM TableT FULL OUTER JOIN TableA on 1=2Since I need a join condition I use 1=2 (never occurs) but is there a way to write it neater it doesn't read very professional |
|
|
gbritton
Master Smack Fu Yak Hacker
2780 Posts |
Posted - 2015-03-13 : 08:49:47
|
CROSS JOIN |
|
|
madlo
Starting Member
41 Posts |
Posted - 2015-03-14 : 07:46:16
|
quote: Originally posted by gbritton CROSS JOIN
Thought cross join would show me multiples of TableA for every row for tableT.I tested it and the results are oddSee belowSELECT ISNULL(A.Col1,B.Col1) as Col1,Col2,Col3 FROM(SELECT 1 Col1,100 Col2 UNION SELECT 2 Col1,200 Col2) ACROSS JOIN(SELECT 1 Col1,300 Col3 UNION SELECT 3 Col1,400 Col3) Bgives me1 100 3001 100 4002 200 3002 200 400Notice how the value 3 doesn't even appear in the output. Odd.However I wantCol1 Col2 Col31 100 NULL2 200 NULL1 NULL 3003 NULL 400which is what full outer join on 1=2 gives meSELECT ISNULL(A.Col1,B.Col1) as Col1,Col2,Col3 FROM(SELECT 1 Col1,100 Col2 UNION SELECT 2 Col1,200 Col2) AFULL OUTER JOIN(SELECT 1 Col1,300 Col3 UNION SELECT 3 Col1,400 Col3) B ON 1=2 |
|
|
madlo
Starting Member
41 Posts |
|
gbritton
Master Smack Fu Yak Hacker
2780 Posts |
Posted - 2015-03-14 : 10:41:01
|
Your problem is what's in your outer select. e.g. If you just select * you'll get:Col1 Col2 Col1 Col31 100 1 3002 200 1 3001 100 3 4002 200 3 400 So, 3 is there, but your ISNULL expression is always selecting from A. Which makes sense since, by definition, a CROSS APPLY is a Cartesian product, so A.col1 will never be null.I agree that the FULL JOIN on a False predicate is unattractive, but on the other hand I can't imagine what your desired results actually would mean. Is this just a toy example or is there a real business problem you are trying to solve? |
|
|
madlo
Starting Member
41 Posts |
Posted - 2015-03-17 : 05:18:42
|
It's a real business case.See it as a budget vs actuals with or without committed in both local and foreign currency including some other columns.Basically 5 unions and thus a lot of false predicates currently which I want to rewrite into a join so it looks neater.The result of the query is passed to a reporting tool which sums it up per account and displays it in one row. The query could also do it, it would make no difference to the end result. |
|
|
gbritton
Master Smack Fu Yak Hacker
2780 Posts |
Posted - 2015-03-17 : 09:51:34
|
OK -- this gives the desired result with the test data. Not sure about your production data though:select isnull(a.Col1, b.col1), case when a.col1 = b.col1 and a.col2 = b.col2 then a.col2 when a.col1 <> b.col1 then b.col2 end as col2, case when a.col1 = b.col1 and a.col2 = b.col2 then null else b.col2 end as col2from (SELECT 1 Col1,100 Col2 UNION SELECT 2 Col1,200 Col2) Afull join ( SELECT 1 Col1,100 Col2 UNION SELECT 2 Col1,200 Col2 union all SELECT 1 Col1,300 Col2 UNION SELECT 3 Col1,400 Col3) b on a.col1 = b.col1return |
|
|
madlo
Starting Member
41 Posts |
Posted - 2015-03-18 : 12:18:27
|
Thanks |
|
|
|
|
|