2014-10-09 16 views
5

In Oracle SQL Developer, sto usando una clausola WITH, in questo (semplificato) modo:SQL: clausola WITH con parametri?

WITH 
foos AS 
    SELECT * 
    FROM my_table 
    WHERE field = 'foo' 
bars AS 
    SELECT * 
    FROM my_table 
    WHERE field = 'bar' 
SELECT * 
FROM foo 
INNER JOIN bar 
ON foo.id = bar.id 

Vorrei essere in grado di scomporre il 'foo' e archi 'bar', in modo che io può avere qualcosa di simile:

WITH 
subq(my_arg) AS 
    SELECT * 
    FROM my_table 
    WHERE field = my_arg 
SELECT * 
FROM subq('foo') 
INNER JOIN subq('bar') 
ON subq('foo').id = subq('foo').id 

Perché, foos e bars sono in realtà molto più grande di questo, e ci sono il dado solo due di loro, così si sta facendo un po 'difficile da mantenere.

So che questo potrebbe non essere possibile con una clausola WITH, ma quale sarebbe la soluzione migliore per evitare di scrivere questa subquery più volte? Questo potrebbe essere in realtà abbastanza semplice, ma sono abbastanza nuovo per SQL ...

Grazie per il vostro aiuto.

risposta

0

Prova questo:

WITH subq AS (
    SELECT * 
    FROM my_table 
) 
SELECT * 
    FROM subq s1 
    , subq s2 
WHERE s1.id = s2.id 
    AND s1.field = 'foo' 
    AND s2.field = 'bar' 

Oppure si può utilizzare pipelined funzione come questa:

CREATE TYPE t_tf_tab IS TABLE OF MY_TABLE%ROWTYPE; 

CREATE OR REPLACE FUNCTION get_table_vals (
    p_val IN VARCHAR 
) 
RETURN t_tf_tab 
PIPELINED 
AS 
BEGIN 
    FOR i IN (SELECT * FROM MY_TABLE WHERE FIELD = p_val) 
    PIPE ROW(t_tf_row(i.id, i.field, ...)); 
    END LOOP; 
    RETURN; 
END; 

SELECT * 
    FROM TABLE(get_table_vals('foo')) s1 
    , TABLE(get_table_vals('bar')) s2 
where s1.id = s2.id 
0

È possibile riutilizzare una con l'espressione in quello successivo. Ma per quanto ne so non puoi parametrizzarlo. Quindi può essere che questo potrebbe aiutare:

WITH 
foosAndbars AS 
    (SELECT * 
    FROM [Very complex query]). 
foos AS (
    SELECT * 
    FROM foosAndbars 
    WHERE field = 'foo'), 
bars AS (
    SELECT * 
    FROM foosAndbars 
    WHERE field = 'bar') 
SELECT * 
FROM foo 
INNER JOIN bar 
ON foo.id = bar.id 
1

Sembra questo può essere ciò che si desidera:

SELECT * 
FROM my_table foo 
JOIN my_table bar ON foo.id = bar.id 
JOIN my_table baz ON foo.id = baz.id 
WHERE foo.field = 'foo' 
AND bar.field = 'bar' 
AND baz.field = 'baz' 

Se la clausola WITH sta facendo un sacco (e vale la pena non ripetere):

WITH cte AS SELECT * FROM mytable <with some complex SQL> 
SELECT * 
FROM cte foo 
JOIN cte bar ON foo.id = bar.id 
JOIN cte baz ON foo.id = baz.id 
WHERE foo.field = 'foo' 
AND bar.field = 'bar' 
AND baz.field = 'baz'