一对一左连接两个表

时间:2015-11-04 20:11:07

标签: postgresql

所以..这是我的查询:

WITH cat AS (
    SELECT day, domain
    FROM table1
    GROUP BY day, domain
), dog AS (
    SELECT day, domain, SUM(count)
    FROM table2
    GROUP BY day, domain
)
SELECT c.domain,
    COALESCE(SUM(d.count),0) AS count
FROM cat c
LEFT JOIN dog d
    ON c.domain = d.domain
    AND c.day <= d.day
GROUP BY c.domain;

以下是“猫”的回报:

    day     |  domain 
------------+-----------
 2015-10-01 | nba.com 
 2015-10-02 | nba.com 

这就是“狗”的回报:

    day     | domain     | count 
------------+----------------+--------
 2015-10-03 | nba.com    |   2 

以下是完整查询返回的内容:

domain     | count 
------------+-------
nba.com    |   4

计数为4,因为LEFT JOIN满足“cat”中的两行。但是,我希望左连接仅应用于ONCE ..(即计数为2而不是4)。这就是“狗”数量为2只应用于ONCE(如果它满足)......并且不超过那个。这可能吗?我希望我在这里有道理

2 个答案:

答案 0 :(得分:2)

你的问题不太清楚。

如果您想找到dog的第一行:

WITH cat AS (
    SELECT day, domain
    FROM table1
    GROUP BY day, domain
), dog AS (
    SELECT day, domain, SUM(count) count
    FROM table2
    GROUP BY day, domain
)
SELECT DISTINCT on (c.domain) c.domain,
    COALESCE(d.count, 0) AS count
FROM cat c
LEFT JOIN dog d
    ON c.domain = d.domain
    AND c.day <= d.day
ORDER BY c.domain, c.day, d.day;

如果要汇总来自dog的所有行(满足条件):

WITH cat AS (
    SELECT day, domain
    FROM table1
    GROUP BY day, domain
), dog AS (
    SELECT day, domain, SUM(count) count
    FROM table2
    GROUP BY day, domain
), cat_and_dogs as (
    SELECT DISTINCT ON(c.domain, d.day) c.domain, d.count
    FROM cat c
    LEFT JOIN dog d
        ON c.domain = d.domain
        AND c.day <= d.day
)
SELECT domain,
    COALESCE(sum(count), 0) AS count
FROM cat_and_dogs
GROUP BY domain;

答案 1 :(得分:0)

基本上,我同意@klin这个问题并不清楚。如果您不希望每次对LEFT JOIN结果中的所有域条目应用cat,则domain列应该是唯一的,因此您不会点击 SUM(count) < / strong>在dog结果中两次。

您可以在count表中使用cat列来简化您的查询,但如果您有理由将它们分开,那么依靠其他一些独特的列可能是一个好主意。加入。

WITH cat(day,domain) AS (
  VALUES
  ('2015-10-01'::DATE,'nba.com'),
  ('2015-10-02'::DATE,'nba.com')
),dog(day,domain,count) AS (
  VALUES
  ('2015-10-03'::DATE, 'nba.com', 1),
  ('2015-10-03'::DATE, 'nba.com', 1)
),dog_data AS (
    SELECT day, domain, SUM(count) count
    FROM dog
    GROUP BY day, domain
), result_to_normilize AS (
    SELECT DISTINCT ON(c.domain,c.day) c.domain,c.day,
      COALESCE(SUM(d.count),0) AS count
    FROM cat c
      LEFT JOIN dog_data d
        ON c.domain = d.domain
           AND c.day <= d.day
    GROUP BY c.domain,c.day
    -- | domain  |    day     | count
    -- | nba.com | 2015-10-01 | 2
    -- | nba.com | 2015-10-02 | 2
)
SELECT DISTINCT ON (r.domain) r.domain, r.count
FROM result_to_normilize r;
  -- | domain  | count
  -- | nba.com | 2