我有两个相同列的表,顺序相同。我希望根据子查询条件加入两个表中的一个。例如,假设我有以下架构:
CREATE TABLE b (
bid SERIAL PRIMARY KEY,
cid INT NOT NULL
);
CREATE TABLE a1 (
aid SERIAL PRIMARY KEY,
bid INT NOT NULL REFERENCES b
);
CREATE TABLE a2 (
aid SERIAL PRIMARY KEY,
bid INT NOT NULL REFERENCES b
);
我想要一个查询,根据某些条件在 a1 或 a2 之间执行连接。类似的东西:
WITH z AS (
SELECT cid, someCondition FROM someTable
)
SELECT *
FROM CASE z.someCondition THEN a1 ELSE a2 END
JOIN b USING (bid)
WHERE cid = (SELECT cid FROM z);
但是,上述方法并不奏效。是否有某种方法可以有条件地连接 a1 或 a2 ,具体取决于存储在表 z 中的某些布尔条件?
答案 0 :(得分:3)
如果条件是独占的(我希望它们是):只需使用智能联合构造两个查询和UNION ALL
它们:
WITH z AS (
SELECT cid
, (cid %3) AS some_condition -- Fake ...
FROM b
)
SELECT *
FROM a1
JOIN b USING (bid)
WHERE EXISTS( SELECT * FROM z
WHERE some_condition = 1 AND cid = b.cid )
UNION ALL
SELECT *
FROM a2
JOIN b USING (bid)
WHERE EXISTS( SELECT * FROM z
WHERE some_condition = 2 AND cid = b.cid )
;
执行相同操作的语法略有不同:
WITH z AS (
SELECT cid
, (cid %3) AS some_condition
FROM b
)
SELECT *
FROM a1
JOIN b ON a1.bid = b.bid
AND EXISTS( SELECT * FROM z
WHERE some_condition = 1 AND cid = b.cid )
UNION ALL
SELECT *
FROM a2
JOIN b ON a2.bid = b.bid
AND EXISTS( SELECT * FROM z
WHERE some_condition = 2 AND cid = b.cid )
;
答案 1 :(得分:2)
SQL语法不允许条件连接。 实现类似效果的最简单方法可能是在plpgsql函数中使用动态查询,如下所示:
create function conditional_select(acid int, some_condition boolean)
returns table (aid int, bid int, cid int)
language plpgsql as $$
declare
tname text;
begin
if some_condition then tname = 'a1';
else tname = 'a2';
end if;
return query execute format ($fmt$
select a.aid, b.bid, b.cid
from %s a
join b using(bid)
where cid = %s;
$fmt$, tname, acid);
end $$;
select * from conditional_select(1, true)
答案 2 :(得分:1)
如果在您的示例中,您只想输出几列,则可以对每列使用CASE
语句:
SELECT CASE z.someCondition THEN a1.aid ELSE a2.aid END AS aid,
CASE z.someCondition THEN a1.bid ELSE a2.bid END AS bid
FROM b
JOIN a1 ON a1.bid = b.bid
JOIN a2 ON a2.bid = b.bid
JOIN someTable z USING (cid);
根据表格a1
和a2
的大小以及您必须输出的列数,这可能或者我不会比Klin的具有函数的解决方案更快,这本质上是比纯SQL慢,尤其是因为动态查询。鉴于z.someCondition
已经是boolean
值,CASE
评估将非常快。小桌子+几列=这个解决方案;大表+多列= Klin的解决方案。