【问题标题】:How to join two tables where the only common field seems to be the date field?如何连接两个表,其中唯一的公共字段似乎是日期字段?
【发布时间】:2022-08-18 15:50:36
【问题描述】:

我在使用这两个表时遇到了问题:

ad_spend

| date    | campaign   | spend |
| ------- | ------    | ----- |
| 1/1/2021|   C       |  500  | 
| 1/1/2021|   D       |  500  |
| 1/1/2021|   C       |  500  | 
| 1/1/2021|   D       |  500  |
| 1/2/2021|   C       |  500  | 
| 1/2/2021|   D       |  500  |
| 1/2/2021|   C       |  500  | 
| 1/3/2021|   D       |  500  |
...

signups_from_ad

| date    | campaign   | customer_id |
| ------- | ------    | ----------- |
| 1/1/2021|   C       |      1      | 
| 1/1/2021|   C       |      2      |
| 1/1/2021|   D       |      3      | 
| 1/1/2021|   C       |      4      |
| 1/2/2021|   C       |      5      | 
| 1/2/2021|   D       |      6      |
| 1/2/2021|   D       |      7      | 
| 1/3/2021|   D       |      8      |
...

我需要从这两个表中创建一个表,该表将按日期和活动返回支出、注册数量以及每次注册的成本,我不知道如何继续。我尝试进行连接,但它们似乎不是正确的解决方案。我知道可以使用联合/联合全部和交叉连接来组合两个没有公共列的表,但我觉得这在这里也没有帮助。提前感谢您的任何建议。

编辑:按照 cmets 中的建议,我重新尝试了这个内部连接:

Select distinct s.date, s.campaign, count(s.customer_id), sum(a.spend), sum(a.spend)/count(s.customer_id) as \'cost\' 
from signups_from_dig as s 
inner join ad_spend as a 
     on a.date=s.date 
group by s.date, s.campaign;

该代码似乎重复计算条目,但我在 count 前面使用了 \"distinct\" 似乎部分修复了它。但是,对 sum 使用 distinct 似乎不起作用(它只计算一次),我不确定如何解决这个问题。

  • 为每个表创建一个子查询,返回日期和活动以及表中所需的统计信息,按日期和活动分组。加入两个子查询。如果每个日期/活动都会有支出并且可能有注册,请左加入注册子查询
  • 在您的示例数据中,所有行在ad_spend 表中都包含相同的spend 值。这是绝对的(该表的值将永远相同)?如果不是,并且该表可能在此列中包含不同的值,则该任务在当前数据上是无法解决的。
  • 您需要重新构建您的表格设计
  • 尝试上面的查询,因为我添加了不同的,所以没有重复的结果
  • 为什么你说唯一的共同字段似乎是日期,当两个表中都有一个名为活动的列,你甚至说你想要结果“按日期和活动”?

标签: mysql sql


【解决方案1】:

按活动和日期聚合表格,然后加入结果。在标准 SQL 中,这将是:

select date, campaign, sp.total_spent, si.total_signups
from
(
  select date, campaign, total_spent
  from ad_spend
  group by date, campaign
) sp
full outer join
(
  select date, campaign, count(*) as total_signups
  from signups_from_ad
  group by date, campaign
) si using (date, campaign)
order by date, campaign;

然而,MySQL 不支持完全外连接。如果保证每个有注册的日期-广告系列对也有一个 ad_spend 行,那么只需将完全连接转换为左外连接。如果不是这种情况,则首先获取不同的日期-广告系列对,然后将聚合表左外连接:

select date, campaign, sp.total_spent, si.total_signups
from
(
  select date, campaign from ad_spend
  union 
  select date, campaign from signups_from_ad
) pairs
left outer join
(
  select date, campaign, total_spent
  from ad_spend
  group by date, campaign
) sp using (date, campaign)
full outer join
(
  select date, campaign, count(*) as total_signups
  from signups_from_ad
  group by date, campaign
) si using (date, campaign)
order by date, campaign;

【讨论】:

    【解决方案2】:

    如果我正确理解您的需求,您需要这样的查询

    SELECT
        *,
        spend/signups AS cost
    FROM (
        SELECT
            s.date,
            s.campaign,
            COUNT(s.customer_id) AS signups,
            (SELECT SUM(ad.spend) FROM ad_spend ad WHERE ad.date = s.date AND ad.campaign = s.campaign) AS spend
        FROM signups_from_dig s
        GROUP BY s.date, s.campaign
    ) t;
    

    它产生

    date campaign signups spend cost
    1/1/2021 C 3 1000 333.3333
    1/1/2021 D 1 1000 1000.0000
    1/2/2021 C 1 1000 1000.0000
    1/2/2021 D 2 500 250.0000
    1/3/2021 D 1 500 500.0000

    您可以查看工作演示 here

    【讨论】:

      【解决方案3】:

      尝试这个

      SELECT ads.date  ,ads.campaign 
      FROM ad_spend ads
      INNER JOIN
      (
          SELECT customer_id ,date
          FROM  signups_from_ad afa
          GROUP BY customer_id,date
          HAVING COUNT(*) = 1 
      ) T
      ON ads.date=T.date  group by ads.campaign, ads.date
      

      【讨论】:

      • 谢谢!我做了你所说的,它似乎返回了一些结果,但是,我遇到了重复值的问题。似乎内部连接使一切都变得双重计数。
      • 不明确的加入条件。
      • 我认为加入日期不是一个好主意。 @elissa 可能在 ad_spend 表中是客户 ID 吗?
      • 2个表之间没有关系,你必须在两个表中都有客户ID,然后只有你得到正确的结果,你不能使用日期或活动,bcz它不是唯一值,正如你所说的使用日期需要加入,所以我提供日期值。
      • 尝试上面的查询,因为我添加了不同的,所以没有重复的结果
      猜你喜欢
      • 2015-10-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-06
      • 2011-03-03
      • 1970-01-01
      • 2022-08-20
      • 1970-01-01
      相关资源
      最近更新 更多