SQL - Relationship between a SubQuery and an Outer Table

前端 未结 3 535
小蘑菇
小蘑菇 2021-01-08 00:55

Problem

I need to better understand the rules about when I can reference an outer table in a subquery and when (and why) that is an inappropriate re

相关标签:
3条回答
  • 2021-01-08 01:38

    So I figured this out based on the comment that Martin Smith made above (THANKS MARTIN!) and I wanted to make sure I shared my discovery for anyone else who trips across this issue.

    Technical Considerations

    Firstly, it would certainly help if I used the proper terminology to describe my problem: My first statement above uses a correlated subquery:

    • http://en.wikipedia.org/wiki/Correlated_subquery
    • http://www.programmerinterview.com/index.php/database-sql/correlated-vs-uncorrelated-subquery/

    This is actually a fairly inefficient way of pulling back data as it reruns the subquery for every line in the outer table. For this reason I'm going to look for ways of eliminating these type of subqueries in my code:

    • https://blogs.oracle.com/optimizer/entry/optimizer_transformations_subquery_unesting_part_1

    My second statement on the other hand was using what is called an inline view in Oracle also known as a derived table in SQL Server:

    • http://docs.oracle.com/cd/B19306_01/server.102/b14200/queries007.htm
    • http://www.programmerinterview.com/index.php/database-sql/derived-table-vs-subquery/

    An inline view / derived table creates a temporary unnamed view at the beginning of your query and then treats it like another table until the operation is complete. Because the compiler needs to create a temporary view when it sees on of these subqueries on the FROM line, those subqueries must be entirely self-contained with no references outside the subquery.

    Why what I was doing was stupid

    What I was trying to do in that second table was essentially create a view based on an ambiguous reference to another table that was outside the knowledge of my statement. It would be like trying to reference a field in a table that you hadn't explicitly stated in your query.

    Workaround

    Lastly, it's worth noting that Martin suggested a fairly clever but ultimately inefficient way to accomplish what I was trying to do. The Apply statement is a proprietary SQL Server function but it allows you to talk to objects outside of your derived table:

    • http://technet.microsoft.com/en-us/library/ms175156(v=SQL.105).aspx

    Likewise this functionality is available in Oracle through different syntax:

    • What is the equivalent of SQL Server APPLY in Oracle?

    Ultimately I'm going to re-evaluate my entire approach to this query which means I'll have to rebuild it from scratch (believe it or not I didn't create this monstrocity originally - I swear!). A big thanks to everyone who commented - this was definitely stumping me but all of the input helped put me on the right track!

    0 讨论(0)
  • 2021-01-08 01:42

    How about the following query:

    SELECT t1.* FROM 
    (
      SELECT * 
      FROM 
      (
        SELECT t2.id,
        RANK() OVER (PARTITION BY t2.id, t2.date ORDER BY t2.date DESC) AS R  
        FROM table2 t2
      )
      WHERE R = 1
    ) sub 
    INNER JOIN table1 t1 
    ON t1.id = sub.id
    
    0 讨论(0)
  • 2021-01-08 01:54

    In your second example you are trying to pass the t1 reference down 2 levels.. you can't do that, you can only pass it down 1 level (which is why the 1st works). If you give a better example of what you are trying to do, we can help you rewrite your query as well.

    0 讨论(0)
提交回复
热议问题