将 JOIN 结果传递给记录并删除重复项
pass JOIN results to a record and erases duplicates
我用的是PostgreSQL 10,这是两张表的结构
nike
id - name - editor_id
adidas
id - name - editor_id
我想做的是select所有的耐克和阿迪达斯都按照一个特定的editor_id
。结果集必须采用以下形式:
id(nike or adidas) - name(nike or adidas) - editor_id - isNike
isNike
是一个布尔值,所以如果为真则为耐克,如果为假则为阿迪达斯。
所以,select 所有 editor_id
的地方,将它们放在特定的形式中,添加布尔标志,避免双打和 return.
我创建了一个 pl/pgsql PostgreSQL 函数
CREATE FUNCTION myfunction(id bigint)
RETURNS TABLE(id bigint, name text, editor_id bigint, isNike boolean)
AS $$
DECLARE
query text;
firstrecord record;
BEGIN
query := '
SELECT
nike.name, nike.id, nike.editor_id,
adidas.name, adidas.id, adidas.editor_id
FROM
adidas left join nike
ON nike.editor_id = adidas.editor_id
WHERE
nike.editor_id ';
FOR myrecord IN
EXECUTE format(query) USING id
LOOP
IF myrecord.adidas.id IS NOT NULL THEN
RETURN QUERY VALUES(myrecord.adidas.id, myrecord.adidas.name, myrecord.adidas.editor_id, false);
END IF;
IF myrecord.pid IS NOT NULL THEN
RETURN QUERY VALUES(myrecord.nike.id, myrecord.nike.name, myrecord.nike.editor_id, true);
END IF;
END LOOP;
RETURN;
END;
$$
LANGUAGE plpgsql;
这行得通,但我的结果翻了一番。我尝试了 select distinct
和 left join
、inner join
或 cross join
的各种组合,但我仍然得到双打,例如:
id - name - editor_id - isNike
1 - aaa - 3 - true
43 - bbb - 9 - false
5 - ccc - 58 - true
1 - aaa - 3 - true --double
我该如何解决这个问题?
谢谢
我觉得你想使用 UNION 功能。
有问题,你说你想拉取特定的editor_id,但是在结果集中,有不同的editor_id。我将假设您想要提取特定 editor_id 的结果(如果不是这种情况,只需从下面的示例中删除 where 子句)。此外,您正在使用存储过程,但如果需要,您可以轻松地将下一个查询放在 sp 中:
SELECT id, name, editor_id, true as is_nike
FROM nike
WHERE editor_id = 3
UNION ALL
SELECT id, name, editor_id, false as is_nike
FROM adidas
WHERE editor_id = 3
注意:我命名 is_nike 而不是 isNike 只是为了遵循一些 PostgreSQL 命名约定(lower_case_with_underscores(名称(标识符)的蛇形))
我用的是PostgreSQL 10,这是两张表的结构
nike
id - name - editor_id
adidas
id - name - editor_id
我想做的是select所有的耐克和阿迪达斯都按照一个特定的editor_id
。结果集必须采用以下形式:
id(nike or adidas) - name(nike or adidas) - editor_id - isNike
isNike
是一个布尔值,所以如果为真则为耐克,如果为假则为阿迪达斯。
所以,select 所有 editor_id
的地方,将它们放在特定的形式中,添加布尔标志,避免双打和 return.
我创建了一个 pl/pgsql PostgreSQL 函数
CREATE FUNCTION myfunction(id bigint)
RETURNS TABLE(id bigint, name text, editor_id bigint, isNike boolean)
AS $$
DECLARE
query text;
firstrecord record;
BEGIN
query := '
SELECT
nike.name, nike.id, nike.editor_id,
adidas.name, adidas.id, adidas.editor_id
FROM
adidas left join nike
ON nike.editor_id = adidas.editor_id
WHERE
nike.editor_id ';
FOR myrecord IN
EXECUTE format(query) USING id
LOOP
IF myrecord.adidas.id IS NOT NULL THEN
RETURN QUERY VALUES(myrecord.adidas.id, myrecord.adidas.name, myrecord.adidas.editor_id, false);
END IF;
IF myrecord.pid IS NOT NULL THEN
RETURN QUERY VALUES(myrecord.nike.id, myrecord.nike.name, myrecord.nike.editor_id, true);
END IF;
END LOOP;
RETURN;
END;
$$
LANGUAGE plpgsql;
这行得通,但我的结果翻了一番。我尝试了 select distinct
和 left join
、inner join
或 cross join
的各种组合,但我仍然得到双打,例如:
id - name - editor_id - isNike
1 - aaa - 3 - true
43 - bbb - 9 - false
5 - ccc - 58 - true
1 - aaa - 3 - true --double
我该如何解决这个问题?
谢谢
我觉得你想使用 UNION 功能。
有问题,你说你想拉取特定的editor_id,但是在结果集中,有不同的editor_id。我将假设您想要提取特定 editor_id 的结果(如果不是这种情况,只需从下面的示例中删除 where 子句)。此外,您正在使用存储过程,但如果需要,您可以轻松地将下一个查询放在 sp 中:
SELECT id, name, editor_id, true as is_nike
FROM nike
WHERE editor_id = 3
UNION ALL
SELECT id, name, editor_id, false as is_nike
FROM adidas
WHERE editor_id = 3
注意:我命名 is_nike 而不是 isNike 只是为了遵循一些 PostgreSQL 命名约定(lower_case_with_underscores(名称(标识符)的蛇形))