在选择不同的行时统一来自不同表的列

Unify columns from different tables while selecting distinct rows

表格

用户

id name email is_active
1 john john@albert.com FALSE
2 mike mike@ss.com TRUE
3 monica monica@dunno.com TRUE
4 joey joey@as.com FALSE
5 ross ross@boss.com FALSE

订阅

id house_id plan name status
1 1 A banana a month inactive
2 2 An apple a month active
3 3 A pear a month active

房子

id name
1 John's House
2 Mike's House
3 Monica's House
4 Joey's House
5 Ross's House

House_Contact(旧版 table)

id house_id is_primary
1 1 TRUE
2 2 FALSE
2 3 TRUE

House_User(新table)

id house_id is_owner user_id
1 2 FALSE 2
2 4 FALSE 4
3 5 FALSE 5

预期结果

生成的 table 应包括以下内容:

house_id email is_owner is_active
1 john@albert.com TRUE FALSE
2 mike@ss.com FALSE TRUE
3 monica@dunno.com TRUE TRUE

我试过的

SELECT
    u.email AS "email",
    u.is_active AS "is_active",
    h.id AS "house_id",
    is_owner
FROM
    house c
    INNER JOIN (
        SELECT
            house_id,
            user_id
        FROM
            house_user) hu ON h.id = hu.house_id
    INNER JOIN (
        SELECT
            id,
            email,
            is_active
        FROM
            USER) u ON hu.user_id = u.id
    INNER JOIN (
        SELECT
            id,
            email,
            is_primary
        FROM
            house_contact) hc ON u.email = ch.email
    INNER JOIN (
        SELECT
            house_id,
            is_primary is_owner
        FROM
            house_contact
    UNION
    SELECT
        house_id,
        is_owner is_owner
    FROM
        house_user) t ON u.id = t.house_id)
ORDER BY
    u.email

结果比我删除 INNER JOIN with UNION 语句的一半。不知道如何进行。

我对统一列和可能的重复感到特别困惑。

您可以按如下方式使用joins

Select distinct hu.house_id, u.email, hu.is_owner, hc.is_primary
  From user u join house_user hu on u.id = hu.user_id
  Join subscriptions s on s.house_id = hu.house_id
  Join house_contract hc on hc.house_id = s.house_id;

如果您在 table 中有多个数据用于匹配条件,我已使用 distinct 删除重复项。不需要的可以去掉。

据我所知,您想从这样的查询开始:

select s.house_id, u.email, hu.is_owner, u.is_active      
from subscriptions s left join
     house_user hu
     on s.house_id = hu.house_id left join
     users u
     on hu.user_id = u.id;

这不是您想要的return,但您的结果是如何得出的还不清楚。

我的有根据的猜测:

SELECT DISTINCT ON (u.id)
      u.id, u.email, u.is_active, h.house_id, h.is_primary
FROM  "user" u
LEFT  JOIN (
   SELECT hu.user_id, hu.house_id
        , GREATEST(hc.is_primary, hu.is_owner) AS is_primary
   FROM   house_user hu
   LEFT   JOIN house_contact hc USING (house_id)
   WHERE  EXISTS (SELECT FROM subscription WHERE house_id = hu.house_id)
   ) h ON h.user_id = u.id
ORDER  BY u.id, h.is_primary DESC NULLS LAST, h.house_id;

我们根本不需要 table house 在查询中。

我看到 三个 可能的冲突来源:

  1. house_contact.is_primary 对比 house_user.is_owner。两者似乎是同一个意思。数据库设计在这方面被打破了。取两者的 GREATEST(),这意味着 true 如果其中一个是 true.

  2. 我们不关心 subscription.status,所以只需确保房子至少有一个订阅任何类型的 EXISTS,从而避免可能的先验重复。

  3. 一个用户可以住多个房子。我们只希望每个用户 one 行。因此,如果有的话,显示第一个 is_primary 的房子(最小 house_id 的那个)。如果没有房子,也没有订阅。但是外面的 LEFT JOIN 让用户留在结果中。更改为 JOIN 以跳过没有订阅的用户。

关于DISTINCT ON

  • Select first row in each GROUP BY group?

关于对布尔值进行排序:

  • Sorting null values after all others, except special
  • Sort NULL values to the end of a table