使用 Redshift 数据库时,SQL Join 或 SUM 返回太多值

Posted

技术标签:

【中文标题】使用 Redshift 数据库时,SQL Join 或 SUM 返回太多值【英文标题】:SQL Join or SUM is returning too many values when working with Redshift database 【发布时间】:2017-02-11 00:22:33 【问题描述】:

我正在使用 Redshift 数据库,但我不明白为什么我的 join 或 SUM 会带来太多值。我的查询如下:

SELECT 
    date(u.created_at) AS date,
    count(distinct c.user_id) AS active_users,
    sum(distinct insights.spend) AS fbcosts,
    count(c.transaction_amount) AS share_shake_costs,
    round(((sum(distinct insights.spend) + count(c.transaction_amount)) / 
    count(distinct c.user_id)),2) AS cac
FROM 
    dbname.users AS u
LEFT JOIN
    dbname.card_transaction AS c ON c.user_id = u.id
LEFT JOIN
    facebookads.insights ON date(insights.date_start) = date(u.created_at)
LEFT JOIN
    dbname.card_transaction AS c2 ON date(c2.timestamp) = date(u.created_at)
WHERE 
    c2.vendor_transaction_description ilike '%share%'
    OR c2.vendor_transaction_description ilike '%shake to win%'
GROUP BY 
    date
ORDER BY 
    1 DESC;

此查询返回以下数据:

如果我们查看 2017-02-08,我们可以看到“share_shake_costs”的总数为 1298。但是,如果我只在 card_transaction 表上运行相同的查询,我会得到以下正确的结果。

第二个表的查询如下所示:

SELECT 
    date(timestamp),
    sum(transaction_amount)
FROM 
    dbname.card_transaction AS c2
WHERE 
    c2.vendor_transaction_description ilike '%share%'
    OR c2.vendor_transaction_description ilike '%shake to win%'
GROUP BY 
    1
ORDER BY 
    1 DESC;

我感觉我的“fbcosts”专栏也有类似的问题。我认为这与我的加入有关,因为 SUM 应该可以正常工作。

我是 Redshift 和 SQL 的新手,所以也许有更好的方法来完成整个查询。我有什么明显的遗漏吗?

【问题讨论】:

一一删除表的连接,直到找出导致重复计数的连接。 (可能有几个) 两个查询运行不同的聚合,因此可能不是很好的比较。请解释模式或表关系(这是一对多的?)。为什么LEFT JOIN dbname.card_transactionusers 两次? 这些连接条件看起来很奇怪。似乎您是在说进行交易的日期/时间必须等于用户记录的创建日期。奇数。 【参考方案1】:

您似乎有一个包含 1:n 映射的表,当您加入一个公共子句时,该数字被计算 n 次。

假设您的一张表orders 包含user_id 和总账单金额,另一张表order_details 包含该用户ID 放置的子项目的详细信息。

如果您进行左连接,根据定义,orders.user_id 将连接 n 次order_details.user_id,其中

n = total number of rows in order_details table

并将执行聚合(求和、计数等)n 次。

+------------------+          +----------------------+
|      orders      |          |    order_details     |
+------------------+          +----------------------+
|amount    user_id |          | user_id       items  |
+------------------+          +----------------------+
| 1000       123   ---------> |   123         apple  |
              +               +----------------------+
              +-------------> |   123         guava  |
              |               +----------------------+
              v-------------> |   123         mango  |
                              +----------------------+

select sum(amount) from orders o left join order_details od 
on o.user_id = od.user_id; // result: 3000

select count(amount) from orders o left join order_details od 
on o.user_id = od.user_id; // result: 3

我希望您现在清楚计数大的原因。

PS:另外,总是喜欢在 () 中包含 OR 条件。

WHERE 
    (c2.vendor_transaction_description ilike '%share%'
    OR c2.vendor_transaction_description ilike '%shake to win%')

【讨论】:

以上是关于使用 Redshift 数据库时,SQL Join 或 SUM 返回太多值的主要内容,如果未能解决你的问题,请参考以下文章

在 Redshift 的 JOIN 中使用模式名称

不能在 Redshift 上使用 JOIN 和 generate_series

在 Redshift 上混合使用 CROSS JOIN 和 LEFT JOIN

在 AWS Redshift 中使用 % JOIN 进行 LIKE

在 Python 中从 JSON 字符串中提取数据时出错(使用 Redshift)

Redshift:将 FULL OUTER 替换为 CROSS JOIN