| Author |
Topic |
|
kbrizendine
Starting Member
12 Posts |
Posted - 2008-05-21 : 16:42:47
|
| I have a situation where my SQL works everywhere else but my COBOL compiler complains wherever I use PARTITION BY. I can't find a workaround for that problem so I would like to remove all the PARTITION BYs. I'm not confident that I can do this accurately and would like some help getting started. Here is my simplest example: SELECT FESOR.REGION, FESOR.TYPE, COUNT(*) OVER (PARTITION BY FESOR.REGION, FESOR.TYPE) FROM FESOR, FR where FESOR.phase = 'Ref' and FESOR.assign is null and FESOR.comp_date is null and FESOR.region = FR.REGION and FESOR.type = FR.TYPE and FR.REP_ROW='A' GROUP BY FESOR.REGION, FESOR.TYPE What I'm looking for is a modified version of the SQL above which returns the same result set without using PARTITION BY.Thanks in advance for your assistance. |
|
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2008-05-21 : 16:44:12
|
You can use a correlated subquery instead and see performance go down the drain. E 12°55'05.25"N 56°04'39.16" |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2008-05-22 : 01:53:50
|
quote: Originally posted by kbrizendine I have a situation where my SQL works everywhere else but my COBOL compiler complains wherever I use PARTITION BY. I can't find a workaround for that problem so I would like to remove all the PARTITION BYs. I'm not confident that I can do this accurately and would like some help getting started. Here is my simplest example: SELECT FESOR.REGION, FESOR.TYPE, COUNT(*) OVER (PARTITION BY FESOR.REGION, FESOR.TYPE) FROM FESOR, FR where FESOR.phase = 'Ref' and FESOR.assign is null and FESOR.comp_date is null and FESOR.region = FR.REGION and FESOR.type = FR.TYPE and FR.REP_ROW='A' GROUP BY FESOR.REGION, FESOR.TYPE What I'm looking for is a modified version of the SQL above which returns the same result set without using PARTITION BY.Thanks in advance for your assistance.
I really cant understand the significance of PARTITION BY here since you're already grouping on the region & type. |
 |
|
|
kbrizendine
Starting Member
12 Posts |
Posted - 2008-05-22 : 09:45:06
|
quote: Originally posted by Peso You can use a correlated subquery instead and see performance go down the drain.
Could you indulge me with the modified SQL? |
 |
|
|
kbrizendine
Starting Member
12 Posts |
Posted - 2008-05-22 : 09:48:44
|
quote: Originally posted by visakh16 I really cant understand the significance of PARTITION BY here since you're already grouping on the region & type.
I see what you mean - but I'm doing my best not to concern myself with the business purpose of the code. I have a bunch of these to fix so I'm just using the result set as a test of success instead of trying to understand each and every one of them. |
 |
|
|
kbrizendine
Starting Member
12 Posts |
Posted - 2008-05-22 : 13:46:40
|
quote: Originally posted by kbrizendine
quote: Originally posted by Peso You can use a correlated subquery instead and see performance go down the drain.
Could you indulge me with the modified SQL?
I've been looking into your suggestion and it seems like it is the only way EXCEPT that, unless I'm mistaken, I would need a unique key in order to implement a correlated subquery however these tables do not have unique keys. Do you agree with my conclusion that the only solution is to add a unique key to one or both tables? |
 |
|
|
Lamprey
Master Smack Fu Yak Hacker
4614 Posts |
Posted - 2008-05-22 : 14:06:32
|
So is this query dynamic sql? I'm assuming that is the case since it is a COBOL compiler complaining. At anyratem I don't see why you need the OVER clause anyway:SELECT FESOR.REGION, FESOR.TYPE, COUNT(*)FROM FESOR, INNER JOIN FR ON FESOR.region = FR.REGION AND FESOR.type = FR.TYPE where FESOR.phase = 'Ref' and FESOR.assign is null and FESOR.comp_date is null and FR.REP_ROW='A'GROUP BY FESOR.REGION, FESOR.TYPE |
 |
|
|
kbrizendine
Starting Member
12 Posts |
Posted - 2008-05-22 : 16:02:38
|
quote: Originally posted by Lamprey So is this query dynamic sql? I'm assuming that is the case since it is a COBOL compiler complaining. At anyratem I don't see why you need the OVER clause anyway:SELECT FESOR.REGION, FESOR.TYPE, COUNT(*)FROM FESOR, INNER JOIN FR ON FESOR.region = FR.REGION AND FESOR.type = FR.TYPE where FESOR.phase = 'Ref' and FESOR.assign is null and FESOR.comp_date is null and FR.REP_ROW='A'GROUP BY FESOR.REGION, FESOR.TYPE
The result set from that SQL is this:REGION_0 TYPE_a 4REGION_0 TYPE_b 4REGION_1 TYPE_a 4REGION_1 TYPE_b 4REGION_2 TYPE_a 1REGION_2 TYPE_b 1Whereas the results set from the original SQL is this:(This is the result set I am trying to match)REGION_0 TYPE_a 1REGION_0 TYPE_b 1REGION_1 TYPE_a 1REGION_1 TYPE_b 1REGION_2 TYPE_a 1REGION_2 TYPE_b 1 |
 |
|
|
Lamprey
Master Smack Fu Yak Hacker
4614 Posts |
Posted - 2008-05-22 : 18:07:13
|
Ahh try this:SELECT FESOR.REGION, FESOR.TYPE, 1FROM FESOR, INNER JOIN FR ON FESOR.region = FR.REGION AND FESOR.type = FR.TYPE where FESOR.phase = 'Ref' and FESOR.assign is null and FESOR.comp_date is null and FR.REP_ROW='A'GROUP BY FESOR.REGION, FESOR.TYPE |
 |
|
|
kbrizendine
Starting Member
12 Posts |
Posted - 2008-05-23 : 10:38:33
|
quote: Originally posted by Lamprey Ahh try this:SELECT FESOR.REGION, FESOR.TYPE, 1FROM FESOR, INNER JOIN FR ON FESOR.region = FR.REGION AND FESOR.type = FR.TYPE where FESOR.phase = 'Ref' and FESOR.assign is null and FESOR.comp_date is null and FR.REP_ROW='A'GROUP BY FESOR.REGION, FESOR.TYPE
Lol - I hope you're joking because otherwise you must think I'm an idiot. |
 |
|
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2008-05-23 : 10:46:11
|
Why not? It produces the resultset you wanted. E 12°55'05.25"N 56°04'39.16" |
 |
|
|
kbrizendine
Starting Member
12 Posts |
Posted - 2008-05-23 : 11:05:22
|
quote: Originally posted by Peso Why not? It produces the resultset you wanted. E 12°55'05.25"N 56°04'39.16"
If I just wanted those characters to appear on my computer screen I could copy and paste them like I did above. Or maybe I could use this SQL statement:select 'REGION_0 TYPE_a 1'UNION ALLselect 'REGION_0 TYPE_b 1'UNION ALLselect 'REGION_1 TYPE_a 1'UNION ALLselect 'REGION_1 TYPE_b 1'UNION ALLselect 'REGION_2 TYPE_a 1'UNION ALLselect 'REGION_2 TYPE_b 1' |
 |
|
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
|
|
Arnold Fribble
Yak-finder General
1961 Posts |
Posted - 2008-05-23 : 12:31:05
|
quote: Originally posted by kbrizendineLol - I hope you're joking because otherwise you must think I'm an idiot.
I think you're missing the point: if you have a count(*) that's partitioned over the same columns that you're grouping by, the answer is necessarily 1. So Lamprey's replacement of the count with just 1 is entirely legitimate. |
 |
|
|
Lamprey
Master Smack Fu Yak Hacker
4614 Posts |
Posted - 2008-05-23 : 12:38:10
|
quote: Originally posted by kbrizendineLol - I hope you're joking because otherwise you must think I'm an idiot.
I don't think your an idiot. I just don't think you understand the SQL you have posted.If you examine your origial query you will see that you are grouping by two columns FESOR.REGION and FESOR.TYPE. So trying to get a COUNT using the OVER operater by PARTITIONING on FESOR.REGION and FESOR.TYPE will always result in a COUNT of 1.So, again, I don't see why you need to use a COUNT since the value is always 1. Here is a sample of what happens:DECLARE @Foo TABLE (ID INT, Val INT)INSERT @FooSELECT 1, 2UNION ALL SELECT 1, 2UNION ALL SELECT 2, 3UNION ALL SELECT 3, 4SELECT ID, Val, COUNT(*) OVER (PARTITION BY ID, Val) aS MyCountFROM @FooGROUP BY ID, Val-- ResultsID Val MyCount----------- ----------- -----------1 2 12 3 13 4 1 |
 |
|
|
kbrizendine
Starting Member
12 Posts |
Posted - 2008-05-23 : 16:31:40
|
quote: Originally posted by Lamprey
quote: Originally posted by kbrizendineLol - I hope you're joking because otherwise you must think I'm an idiot.
I don't think your an idiot. I just don't think you understand the SQL you have posted.If you examine your origial query you will see that you are grouping by two columns FESOR.REGION and FESOR.TYPE. So trying to get a COUNT using the OVER operater by PARTITIONING on FESOR.REGION and FESOR.TYPE will always result in a COUNT of 1.So, again, I don't see why you need to use a COUNT since the value is always 1. Here is a sample of what happens:DECLARE @Foo TABLE (ID INT, Val INT)INSERT @FooSELECT 1, 2UNION ALL SELECT 1, 2UNION ALL SELECT 2, 3UNION ALL SELECT 3, 4SELECT ID, Val, COUNT(*) OVER (PARTITION BY ID, Val) aS MyCountFROM @FooGROUP BY ID, Val-- ResultsID Val MyCount----------- ----------- -----------1 2 12 3 13 4 1
Ok, I see your point but as I mentioned in my original post this is only one very simple example. My goal is not simply conversion of this SQL script such that I may be able to produce the same result set - it is to establish a methodology for converting ALL my SQL scripts that use PARTITION BY. So the fact that we may be able to use a trick to get the results I gave with the sample data I created only for testing doesn't help achieve my goal. But I can see now why you would not have realized that before now. |
 |
|
|
kbrizendine
Starting Member
12 Posts |
Posted - 2008-05-23 : 16:43:36
|
quote: Originally posted by Peso Why not? It produces the resultset you wanted. E 12°55'05.25"N 56°04'39.16"
Pedo,I think I did provide everything needed to answer this question and I believe you gave the correct answer. As i posted above:I've been looking into your suggestion and it seems like it is the only way EXCEPT that, unless I'm mistaken, I would need a unique key in order to implement a correlated subquery however these tables do not have unique keys. Do you agree with my conclusion that the only solution is to add a unique key to one or both tables?Do you agree? |
 |
|
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2008-05-23 : 16:43:53
|
You can't establish a methodolgy for all PARTITION BY.They can partition for other columns that you GROUP BY.For example - ROW_NUMBER() OVER (PARTITION BY ..) can either be solved with 1) Correlated subquery2) temp table with identity columnIf you must make a generic solution, correlated subquery will do in most cases. E 12°55'05.25"N 56°04'39.16" |
 |
|
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2008-05-23 : 16:46:49
|
quote: Originally posted by kbrizendine Do you agree?
No. You can make correlated subqueries on composite keys too. E 12°55'05.25"N 56°04'39.16" |
 |
|
|
Lamprey
Master Smack Fu Yak Hacker
4614 Posts |
Posted - 2008-05-23 : 16:52:56
|
| Do you have some more examples and maybe some sample data? Obviously the first sample query you showed can be simplified to remove the OVER clause. But, if there are other cases then let us know and maybe we can help come up with a generic solution for replacing the OVER clause for all of them.Actualy, I'm more curious about why your COBOL compiler is complaining. Do you have some more detail on that? As I asked previously; is the dynamic sql? |
 |
|
|
kbrizendine
Starting Member
12 Posts |
Posted - 2008-05-23 : 17:57:02
|
quote: Originally posted by Peso
quote: Originally posted by kbrizendine Do you agree?
No. You can make correlated subqueries on composite keys too. E 12°55'05.25"N 56°04'39.16"
Unfortunately there is no unique key whatsoever on FR. |
 |
|
|
Next Page
|