2014-10-09 32 views
5

W Oracle SQL Developer, używam klauzuli WITH, w tym (uproszczony) sposób:SQL: Z klauzulą ​​z parametrami?

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 

Chciałbym móc czynnik zewnątrz 'foo' i sznurki 'bar', tak że może mieć coś takiego:

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 

Bo foos i bars rzeczywistości są dużo większe niż to, i istnieje nakrętka tylko dwa z nich, więc robi się nieco trudne do utrzymania.

Wiem, że to może nie być możliwe z klauzulą ​​WITH, ale jakie byłoby najlepsze rozwiązanie, aby uniknąć wielokrotnego pisania tego podzapytania? To może być całkiem proste, ale jestem całkiem nowy w SQL ...

Dzięki za pomoc.

Odpowiedz

0

Spróbuj tego:

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' 

Albo można użyć pipelined funkcja tak:

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

można ponownie użyć z ekspresją w następnym. Ale o ile wiem, nie można go parametryzować. Więc może być to może pomóc:

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

Wydaje się to może być to, co chcesz:

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' 

Jeśli klauzuli WITH robi dużo (i warto nie powtarzać):

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'