【发布时间】:2022-01-20 20:08:19
【问题描述】:
注意:SQL后端无所谓,任何主流关系型数据库都可以(postgres、mysql、oracle、sqlserver)
有一个有趣的article on Looker 讲述了当 JOIN 导致扇出时他们用来提供正确总计的技术,大致如下:
# In other words, using a hash to remove any potential duplicates (assuming a Primary Key).
SUM(DISTINCT big_unique_number + total) - SUM(DISTINCT big_unique_number)
一种模拟扇出的好方法,只需执行以下操作:
WITH Orders AS (
SELECT 10293 AS id, 2.5 AS rate UNION ALL
SELECT 210293 AS id, 3.5
),
Other AS (
SELECT 1 UNION ALL SELECT 2
)
SELECT SUM(rate) FROM Orders CROSS JOIN Other
-- Returns 12.0 instead of 6.0
他们的例子做了这样的事情,我认为这只是一种通过所有花哨的步法来获取md5(PK) 以绕过 8 字节限制的长形式(所以他们先是 LEFT(...) 然后是 @987654328 @:
(COALESCE(CAST( ( SUM(DISTINCT (CAST(FLOOR(COALESCE(users.age ,0)
*(1000000*1.0)) AS DECIMAL(38,0))) +
CAST(STRTOL(LEFT(MD5(CONVERT(VARCHAR,users.id )),15),16) AS DECIMAL(38,0))
* 1.0e8 + CAST(STRTOL(RIGHT(MD5(CONVERT(VARCHAR,users.id )),15),16) AS DECIMAL(38,0)) )
- SUM(DISTINCT CAST(STRTOL(LEFT(MD5(CONVERT(VARCHAR,users.id )),15),16) AS DECIMAL(38,0))
* 1.0e8 + CAST(STRTOL(RIGHT(MD5(CONVERT(VARCHAR,users.id )),15),16) AS DECIMAL(38,0))) )
AS DOUBLE PRECISION)
/ CAST((1000000*1.0) AS DOUBLE PRECISION), 0)
还有其他通用方法可以做到这一点吗?也许使用相关的子查询或其他东西?或者上述方式是最知名的方式吗?
两个相关的答案:
无需担心通用散列函数(例如,可能采用字符串),以下工作:
WITH Orders AS (
SELECT 10293 AS id, 2.5 AS rate UNION ALL
SELECT 210293 AS id, 3.5
),
Other AS (
SELECT 1 UNION ALL SELECT 2
)
SELECT SUM(DISTINCT id + rate) - SUM(DISTINCT id) FROM Orders CROSS JOIN Other
-- 6.0
但这仍然引出了一个问题:是否有另一种/更好的方法可以以非常通用的方式做到这一点?
【问题讨论】:
-
一些示例数据会对您的问题有所帮助,因为它不会强迫读者阅读外部文章来理解。
-
@TimBiegeleisen 我刚刚用一个有效的查询更新了它,你想让我知道它是否有效吗?
-
为什么不在第一个子查询
WITH Orders AS(...)中直接计算sum(rate)? -
我删除了冲突的 DBMS 标签。请为您真正使用的数据库产品添加一个标签(您的查询一开始在 Postgres 或 Oracle 中不起作用)。如果你想要一个独立于 DBMS 的答案,那么
sql标签就足够了。 -
@David542 - 是的,我同意你的观点,这是一个 CTE 而不是子查询......但我的问题仍然有效:你为什么不直接在 CTE @987654335 中计算
sum(rate)@?这将使查询更加简单、可读和高效,不是吗?
标签: sql