IWETHEY v. 0.3.0 | TODO
1,095 registered users | 2 active users | 0 LpH | Statistics
Login | Create New User
IWETHEY Banner

Welcome to IWETHEY!

New One approach
Here goes:

\nSELECT *\nFROM\n  drug d\n  LEFT OUTER JOIN (\n    SELECT f.*\n    FROM\n      formulary f\n      INNER JOIN (\n        SELECT MIN(formularyid) AS formularyid\n        FROM formulary\n        GROUP BY drugid\n      ) top\n      ON f.formularyid = top.formularyid\n    ) f\n    ON (f.drugid = d.drugid)\n


(I got this from adapting a trick I've developed with analytic functions in Oracle. But you can implement this special case without analytic functions.)

Cheers,
Ben

PS I should note that this solution is untested. I don't guarantee that there aren't silly syntax errors or worse.

PPS I swear that when I posted it I had indentation. :-(
I have come to believe that idealism without discipline is a quick road to disaster, while discipline without idealism is pointless. -- Aaron Ward (my brother)
Expand Edited by ben_tilly June 8, 2006, 12:05:30 AM EDT
Expand Edited by ben_tilly June 8, 2006, 01:13:51 PM EDT
New Some variation on MIN...
...should do the trick. My concern would be in performance, as these are rather large tables and I'm not sure whether the constraints that are outside of the inner views/queries will limit the returned rows - or whether they will build the table the with all the mins and then do a join across to the temporary table. Should be easy enuf to test - since they are large tables, it should be obvious if there's a performance hit.

Anyhow, now that you've got me past my memory block, I should be able to come up with a query. Thanks.
New It probably will not optimize
My experience suggests that complex queries without group bys can be optimized. But as soon as you add a group by, that level of nesting becomes "opaque" to the query analyzer which then does the whole group by only to filter later.

The workaround that I've used for that is to stick inner inner queries in that create a condition that greatly reduces the size of that subselect. As you might imagine, this makes queries rather heinous with lots of duplicated information, so when I do this I typically also switch over to writing code to generate the SQL.

In fact that's usually how I handle complex queries. It is a lot easier to read code that produces SQL, and it is far easier to edit. With the query that I wrote above I might write something like this:
\nmy $formularyid_by_drugid_sql = qq{\n  SELECT MIN(formularyid) AS formularyid\n  FROM formulary\n  GROUP BY drugid\n};\n\nmy $full_formulary_by_drugid_sql = qq{\n  SELECT f.*\n  FROM\n    formulary f\n    INNER JOIN (}\n      . indent($formularyid_by_drugid_sql)\n      . qq{    ) top\n    ON f.formularyid = top.formularyid\n};\n\nmy $drug_and_formulary_isql = qq{\n  SELECT *\n  FROM\n    drug d\n    LEFT OUTER JOIN (}\n      . indent($full_formulary_by_drugid_sql)\n      . qq{    ) f\n    ON d.drugid = f.drugid\n};\n


And now I find the structure of the query somewht easier to interpret.

BTW this wasn't the best example of the technique. It makes more of a difference when you have multiple subqueries and/or interesting WHERE conditions on some subqueries.

Cheers,
Ben
I have come to believe that idealism without discipline is a quick road to disaster, while discipline without idealism is pointless. -- Aaron Ward (my brother)
New Yep, took forever to run.
But I did end up figuring out a SS solution using the min function (in non-SQL-standard sort of fashion).

SELECT *\nFROM\n   drug d\n   LEFT OUTER JOIN formulary f ON (f.drugid = d.drugid)\nWHERE\n   ((f.formularyid IS NULL) OR\n    (f.formularyid = (\n       SELECT MIN(forumularyid)\n       FROM formulary x\n       WHERE (x.drugid = d.drugid))))

New Nothing non-standard about that
In fact, that's the solution I'd like to think I'd have come up with if I'd worked on it long enough.
===

Purveyor of Doc Hope's [link|http://DocHope.com|fresh-baked dog biscuits and pet treats].
[link|http://DocHope.com|http://DocHope.com]
New Pre indentation
PPS I swear that when I posted it I had indentation. :-(

There's a quirk in the forum software where editing an old post that has a pre statement will forget the spaces and indentation. I noticed it when I edited the post up above.
New Bug, indentation can be lost during edits (new thread)
Created as new thread #258179 titled [link|/forums/render/content/show?contentid=258179|Bug, indentation can be lost during edits]
I have come to believe that idealism without discipline is a quick road to disaster, while discipline without idealism is pointless. -- Aaron Ward (my brother)
     Left Outer Join question - (ChrisR) - (20)
         One approach - (ben_tilly) - (6)
             Some variation on MIN... - (ChrisR) - (3)
                 It probably will not optimize - (ben_tilly) - (2)
                     Yep, took forever to run. - (ChrisR) - (1)
                         Nothing non-standard about that - (drewk)
             Pre indentation - (ChrisR) - (1)
                 Bug, indentation can be lost during edits (new thread) - (ben_tilly)
         Does SQL Server support "DISTINCT ON"? - (drewk) - (12)
             That is really what I need! - (ChrisR)
             The more readable version is invalid (at least in Oracle) - (ben_tilly) - (10)
                 Hmm, both Postgres and MySQL support the same non-standard? - (drewk) - (9)
                     Can you please help me find mine? - (folkert)
                     That is a MySQL shortcut - (ben_tilly) - (7)
                         Not surprising - (drewk) - (2)
                             Or you didn't double-check enough - (ben_tilly) - (1)
                                 Also possible - (drewk)
                         I've encountered that problem. - (static) - (3)
                             Justifiable arrogance in many cases - (ben_tilly) - (2)
                                 Oh I have little doubt about that. - (static) - (1)
                                     Oracle is picky but... - (ben_tilly)

Gimme some sugar, baby.
65 ms