2014-10-09 6 views
5

In Oracle SQL Developer, ich bin mit einem WITH-Klausel, in dieser (vereinfachte) Art und Weise:SQL: WITH-Klausel mit Parametern?

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 

Ich mag wäre in der Lage sein, die 'foo' Faktor und 'bar' Strings, so dass ich etwas ähnliches:

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 

Denn foos und bars tatsächlich viel größer als diese sind, und es gibt Mutter nur zwei von ihnen, so ist es ein bisschen schwer bekommen zu halten.

Ich weiß, dass dies möglicherweise nicht mit einer WITH-Klausel möglich ist, aber was wäre die beste Lösung, um zu vermeiden, diese Unterabfrage mehrmals zu schreiben? Das kann eigentlich ganz einfach sein, aber ich bin ziemlich neu in SQL ...

Vielen Dank für Ihre Hilfe.

Antwort

0

Versuchen Sie folgendes:

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' 

Oder können Sie pipelined Funktion wie folgt verwendet werden:

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

Sie ein MIT-Expression in den nächsten wiederverwenden können. Aber soweit ich weiß, kann man es nicht parametrisieren. So kann dies helfen könnte:

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

Es scheint dies auch sein mag, was Sie wollen:

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' 

Wenn die WITH-Klausel wird eine Menge zu tun (und lohnt sich zu wiederholen nicht):

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'