【问题标题】:Postgres nested LEFT OUTER JOIN returns me more than one null in array_agg()Postgres 嵌套的 LEFT OUTER JOIN 在 array_agg() 中返回多个 null
【发布时间】:2016-05-07 20:56:19
【问题描述】:

我有两张桌子:

SELECT * FROM clubs_place_rubrics;
  id   | place_id | placerubric_id 
-------+----------+----------------
 20777 |     3626 |              7
(1 row)

SELECT * FROM clubs_placerubric LIMIT 5;
 id |         rubric         
----+------------------------
  1 | Тренажёрные залы
  2 | Фитнес-клубы
  3 | Косметические услуги
  4 | Услуги массажиста
  5 | Ледовые дворцы / Катки

所以有些俱乐部有或根本没有评分标准。从上面的例子中,只有一个俱乐部 (id=3626) 有评分准则 #7。

那么为什么这段代码会返回一个空值列表,不止一个空值?

        SELECT
            place.id, place.title, 
            array_agg(phone.code) phone_code, 
            array_agg(phone.phone) phone_number, 
            array_agg(phone.fax) fax,
            array_agg(email.email) email, 
            array_agg(site.site) site,
            array_agg(rubric.rubric) rubrics
        FROM clubs_place place 
            LEFT OUTER JOIN clubs_placephone phone 
            ON place.id = phone.place_id 
            LEFT OUTER JOIN clubs_placeemail email
            ON place.id = email.place_id 
            LEFT OUTER JOIN clubs_placesite site
            ON place.id = site.place_id 
                LEFT OUTER JOIN clubs_place_rubrics rubrics
                ON place.id = rubrics.place_id
                LEFT OUTER JOIN clubs_placerubric rubric
                ON rubric.id = rubrics.placerubric_id

        WHERE project='Москва'
        GROUP BY place.id
        LIMIT 6;


-[ RECORD 4 ]+-----------------------------------------------------------------------
id           | 3629
title        | Переделкино, банно-оздоровительный комплекс
phone_code   | {499,495}
phone_number | {7379358,7311313}
fax          | {t,t}
email        | {gup@gup-bok.ru,gup@gup-bok.ru}
site         | {www.gup-bok.ru,www.gup-bok.ru}
rubrics      | {NULL,NULL}
-[ RECORD 5 ]+-----------------------------------------------------------------------
id           | 3630
title        | Досуг и здоровье, физкультурно-оздоровительный комплекс
phone_code   | {499}
phone_number | {1281877}
fax          | {f}
email        | {""}
site         | {www.apollon.ru}
rubrics      | {NULL}
-[ RECORD 6 ]+-----------------------------------------------------------------------
id           | 3631
title        | Центр Корона, спортивно-развлекательный центр
phone_code   | {495,495,495}
phone_number | {7532650,7540511,7941880}
fax          | {f,f,f}
email        | {centr-corona@yandex.ru,centr-corona@yandex.ru,centr-corona@yandex.ru}
site         | {"","",""}
rubrics      | {NULL,NULL,NULL}

评分标准的数量似乎与电话数量相同。但是没有逻辑。我想,我在 SQL 语法上犯了一个错误。

在评分量规的结果列表中肯定不应该有超过一个空值。网站、电子邮件和所有其他行也一样,没有任何价值。

如何解决这个问题?

谢谢。

【问题讨论】:

  • 这是有道理的,如果您在 club_places 中有超过 2 个 id,那么它只会将您的示例中的 placeid 为 3626 的那些 id 连接起来,所以其余的将为空
  • 使用array_agg(distinct rubric.rubric) 删除重复值。
  • 谢谢@Abelisto,您能否快速解释一下为什么会发生这种情况?我对 SQL 完全陌生。非常感谢。
  • @kAldown 如果你是 SQL 的新手,那么快速是不可能解释清楚的 :) 祝你好运。

标签: sql postgresql join nosql-aggregation


【解决方案1】:

如果这些表中有多个条目:

LEFT OUTER JOIN clubs_placephone phone 
ON place.id = phone.place_id 
LEFT OUTER JOIN clubs_placeemail email
ON place.id = email.place_id 
LEFT OUTER JOIN clubs_placesite site
ON place.id = site.place_id 

那么您将拥有多个地点记录,并且您的

LEFT OUTER JOIN clubs_place_rubrics rubrics
ON place.id = rubrics.place_id

多次加入时会加入。聚合后,这些多行的 NULL 将显示在聚合中。

您能否确认 place_id 在以下任何一个中都没有重复:clubs_placephone、clubs_placeemail 和 clubs_placesite?

如果有重复,那么您可能希望使用子查询来一对一地进行连接以避免重复。

【讨论】:

    猜你喜欢
    • 2023-03-26
    • 2018-12-04
    • 1970-01-01
    • 2012-06-21
    • 1970-01-01
    • 2022-09-29
    • 1970-01-01
    • 2020-04-25
    • 1970-01-01
    相关资源
    最近更新 更多