why don’t you use a NOT EXISTS correlated subquery?  that way the subquery can 
refer to the outer table completely, rather than having just one column where 
you can call IN.



> On Dec 3, 2014, at 12:36 PM, Stefan Urbanek <stefan.urba...@gmail.com> wrote:
> 
> Hi,
> 
> How can I reference a table that I am deleting from in an inner/nested 
> statement?
> 
> Here is my simplified oritinal version, no inner condition:
> 
>    rownum = sql.expression.over(sql.func.row_number(),
>                                 partition_by=table.c.some_id,
>                                 order_by=table.c.dw_created_date.desc())
>    rownum = rownum.label("rownum")
> 
>    condition = table.c.dw_valid_to_date == None
> 
>    primary = sql.expression.select([table.c.dw_some_key, rownum])
>    primary = primary.where(condition).alias("primary")
> 
>    condition = primary.c.rownum == 1
>    unique = sql.expression.select([primary.c.dw_some_key])
>    unique = unique.where(condition).alias("unique")
>    condition = table.c.dw_some_key.notin_(unique)
>    delete = sql.expression.delete(table,
>                                   whereclause=condition)
> 
> Which produces something like the following (manually formatted + added 
> comments about my intention):
> 
> DELETE FROM foo a
> WHERE a.dw_key NOT IN
> (
>    SELECT "primary".dw_key 
>    FROM (
>        SELECT foo.dw_key AS dw_key,
>                row_number() OVER (PARTITION BY foo.some_id
>                             ORDER BY foo.dw_created_date DESC) AS rownum 
>        FROM foo 
>        WHERE foo.dw_valid_to_date IS NULL
> 
>        -- Need to add this:
>        -- AND a.some_id = foo.some_id
> 
>    ) AS "primary" 
>    WHERE "primary".rownum = 1
> )
> 
> I want to add the condition commented-out in the above statement. My attempt 
> was to alias the table:
> 
> Aliased version with inner condition:
> 
>    inner = table.alias("inner")
>    rownum = sql.expression.over(sql.func.row_number(),
>                                 partition_by=inner.c.some_id,
>                                 order_by=inner.c.dw_created_date.desc())
>    rownum = rownum.label("rownum")
> 
>    condition = inner.c.dw_valid_to_date == None
>    condition = and_(inner.c.dw_valid_to_date == None,
>                     inner.c.some_id == table.c.some_id)
> 
>    primary = sql.expression.select([inner.c.dw_some_key, rownum])
>    primary = primary.where(condition).alias("primary")
> 
>    # Select unique and filter non-unique
>    # 
> 
>    condition = primary.c.rownum == 1
>    unique = sql.expression.select([primary.c.dw_some_key])
>    unique = unique.where(condition).alias("unique")
>    condition = table.c.dw_some_key.notin_(unique)
>    delete = sql.expression.delete(table,
>                                   whereclause=condition)
> 
> 
> However this produces a product of the inner statement and the original table:
> 
> DELETE FROM footable
> WHERE footable.dw_some_key NOT IN (
>    SELECT "primary".dw_some_key
>    FROM (
>        SELECT "inner".dw_some_key AS dw_some_key, row_number()
>                    OVER (PARTITION BY "inner".some_id
>                          ORDER BY "inner".dw_created_date DESC) AS rownum 
>        #
>        # Here is the problem introduced by the alias:
>        #
>        FROM footable AS "inner", footable 
>        WHERE "inner".dw_valid_to_date IS NULL
>            AND "inner".some_id = footable.some_id) AS "primary" 
>    WHERE "primary".rownum = 1
> 
> You can see that the inner condition is not referencing the table used in the 
> DELETE statement but a new reference to the table.
> 
> How can I construct a statement where I can reference the tables as I need to 
> in my case?
> 
> Thanks for any hints,
> 
> Stefan
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "sqlalchemy" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to sqlalchemy+unsubscr...@googlegroups.com.
> To post to this group, send email to sqlalchemy@googlegroups.com.
> Visit this group at http://groups.google.com/group/sqlalchemy.
> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.

Reply via email to