在Oracle SQL Developer中,我使用WITH子句,采用这种(简化)方式:
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
我希望能够将“foo”和“bar”字符串分解出来,以便我可以拥有类似的内容:
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
因为,foos
和bars
实际上比这要大得多,而且其中只有两个,所以维护起来有点困难。
我知道使用WITH子句可能无法做到这一点,但是避免多次编写此子查询的最佳解决方案是什么?这实际上可能很简单,但我对SQL很新......
感谢您的帮助。
答案 0 :(得分:1)
看起来这可能是你想要的:
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'
如果WITH子句做了很多(并且不值得重复):
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'
答案 1 :(得分:0)
试试这个:
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'
或者您可以使用pipelined这样的功能:
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
答案 2 :(得分:0)
您可以在下一个表达式中重用WITH表达式。但据我所知,你不能参数化它。所以这可能会有所帮助:
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