我正在尝试创建一个联系人报告,显示所有联系人并选择那些在场的人。
存在存储在多对多表中。文件ID和谁在场。
表格如下:
CREATE TABLE pe
(peid int4, peco int4, pename varchar(30));
INSERT INTO pe
(peid, peco, pename)
VALUES
(1, 1,'Carl'),
(2, 1,'John'),
(3, 1,'Eric'),
(4, 2,'Donald')
;
CREATE TABLE co
(coid int, coname varchar(30));
INSERT INTO co
(coid, coname)
VALUES
(1,'Volvo'),
(2,'BMW'),
(3,'Microsoft'),
(4,'Apple')
;
There is a also a doc table that is not needed for this query
CREATE TABLE pres
(presid int4, presdoc int4, prespe int4);
INSERT INTO pres
(presid, presdoc, prespe)
VALUES
(1,1,1),
(2,2,2),
(3,2,3),
(4,3,1)
;
不起作用的查询(无论连接类型如何):
SELECT pename,coname,presdoc AS present
FROM pe
LEFT JOIN co ON coid=peco
LEFT JOIN pres ON prespe=peid
WHERE peco = 1 AND presdoc=2
此查询的输出是
John Volvo present
Eric Volvo present
所需的输出是
Carl Volvo
John Volvo present
Eric Volvo present
SQLFiddle:
http://sqlfiddle.com/#!15/77b09/21
提前感谢任何线索。
答案 0 :(得分:1)
我认为问题在于条件presdoc=2
迫使只返回存在的记录。这就是你需要的。
的 SQLFiddle Demo
强>
SELECT pename,
coname,
CASE
WHEN presdoc=2 THEN 'Present'
ELSE NULL
END AS Present
FROM pe
LEFT JOIN co ON coid=peco
LEFT JOIN pres ON prespe=peid
WHERE peco = 1
GROUP BY pename,
coname,
present
答案 1 :(得分:1)
你可以这样做(如果你只需要检查是否存在)
SELECT pename,coname,presdoc = 2 AS present
FROM pe
LEFT JOIN co ON coid=peco
LEFT JOIN pres ON prespe=peid
WHERE peco = 1
甚至更好
SELECT DISTINCT pename,coname,presdoc = 2 AS present
FROM pe
LEFT JOIN co ON coid=peco
LEFT JOIN pres ON prespe=peid
WHERE peco = 1
答案 2 :(得分:0)
如果您想检查一下您的文件是否已经发出。然后你可以为你的布尔检查创建自定义聚合,逻辑就像“一旦达到真实就变成并保持真实”:
create or replace function max_boolean(agg_state boolean)
returns boolean
immutable
strict
language plpgsql
as $$
begin
return agg_state;
end;
$$;
create or replace function max_boolean_aggregate(agg_state boolean, el boolean)
returns boolean
immutable
language plpgsql
as $$
begin
if (agg_state = true) then
return true;
else
if (el is null) then
return false;
else
return el;
end if;
else
return el;
end if;
end;
$$;
create aggregate max_boolean_aggregate (boolean)
(
sfunc = max_boolean_aggregate,
stype = boolean,
finalfunc = max_boolean
);
然后您的查询可以重写如下:
SELECT DISTINCT pename,coname, max_boolean_aggregate(presdoc = 2) AS present
FROM pe
left JOIN co ON coid=peco
left JOIN pres ON prespe=peid
WHERE peco = 1
group by pename, coname
它会显示您的人是否收到了该文件。
甚至可以支持多项检查:-)
只需将max_boolean_aggregate()内的条件更改为(2,3)中的presdoc就可以了。
答案 3 :(得分:0)
基本上@Ilya Dyoshin有解决方案。我只是把他的小评论写进了答案。首先找到现有的,然后UNION不存在。使用NOT IN比不存在恕我直言更简单。
photoGallery
SQLFiddle:http://sqlfiddle.com/#!15/fb571/117
谢谢!