RedShift GROUP BY常量列给出的结果不一致

Eri*_*ert 5 sql amazon-redshift

我想知道是否有人可以帮助解释为什么GROUP BY在常数列上使用VARCHARvs. INTEGER给出不同行为的列。

这是我的最小工作示例。下表模拟了我发现此问题的真实数据:

CREATE TABLE test.show_bug AS

WITH integers AS (
    SELECT 0 AS num
    UNION SELECT 1 AS num
    UNION SELECT 2 AS num
    UNION SELECT 3 AS num
    UNION SELECT 4 AS num
    UNION SELECT 5 AS num
)
SELECT 
    '2017-03-16' + mod(a.num, 2) AS date_time 
    , CASE mod(b.num, 3)
        WHEN 0 THEN 'source_a'
        WHEN 1 THEN 'source_b'
        WHEN 2 THEN 'source_c'
        END AS user_source
    , b.num || a.num || b.num || a.num || b.num AS user_id
FROM integers AS a
CROSS JOIN integers AS b
;
Run Code Online (Sandbox Code Playgroud)

看起来像:

 date_time  | user_source | user_id
------------+-------------+---------
 2017-03-17 | source_a    | 3113313
 2017-03-17 | source_b    | 4114414
 2017-03-17 | source_b    | 1111111
 2017-03-16 | source_a    | 0000000
 2017-03-16 | source_c    | 2442242
 2017-03-16 | source_c    | 5225525
....
(36 rows)
Run Code Online (Sandbox Code Playgroud)

本质上,我希望能够COUNT(每天)获得用户数量,来源数量以及每个来源的用户数量。但是,我有两个相同格式的不同表,它们要从中UNION一起取到结果。我可以通过添加恒定列于每个区分这些结果:app_1app_2

为了示例,我使用了相同的模拟表两次,但是在实际应用程序中,我有两个不同的表,无论哪种方式,以下sql应该都能得到我想要的结果:

SELECT 
    'app_1' AS app
    , date_time
    , COUNT(user_source)
    , COUNT(DISTINCT user_source)
    , COUNT(DISTINCT user_id)
FROM test.show_bug
GROUP BY 1, 2

UNION

SELECT 
    'app_2' AS app
    , date_time
    , COUNT(user_source)
    , COUNT(DISTINCT user_source)
    , COUNT(DISTINCT user_id)
FROM test.show_bug
GROUP BY 1, 2
Run Code Online (Sandbox Code Playgroud)

这导致

   app    |     date_trunc      | count | count1 | count2
----------+---------------------+-------+--------+--------
 app_1    | 2017-03-16 00:00:00 |     2 |      1 |      0
 app_1    | 2017-03-17 00:00:00 |     2 |      1 |      0
 app_1    | 2017-03-19 00:00:00 |     5 |      0 |      1
 app_2    | 2017-03-19 00:00:00 |     7 |      1 |      0
 app_1    | 2017-03-16 00:00:00 |     0 |      1 |      0
....
(112 rows)
Run Code Online (Sandbox Code Playgroud)

因为什么其实我希望是用整数值达到其结果是不正确的1,并2在地方的VARCHAR价值观app_1app_2,也就是这样的:

SELECT 
    1 AS app
    , date_time
    , COUNT(user_source)
    , COUNT(DISTINCT user_source)
    , COUNT(DISTINCT user_id)
FROM test.show_bug
GROUP BY 1, 2

UNION

SELECT 
    2 AS app
    , date_time
    , COUNT(user_source)
    , COUNT(DISTINCT user_source)
    , COUNT(DISTINCT user_id)
FROM test.show_bug
GROUP BY 1, 2
Run Code Online (Sandbox Code Playgroud)

这给了我:

   app    |     date_trunc      | count | count1 | count2
----------+---------------------+-------+--------+--------
        1 | 2017-03-16 00:00:00 |   192 |     16 |    192
        1 | 2017-03-17 00:00:00 |   208 |     14 |    208
        1 | 2017-03-18 00:00:00 |   203 |     14 |    203
        1 | 2017-03-19 00:00:00 |   203 |     14 |    203
        1 | 2017-03-20 00:00:00 |    35 |      0 |     35
        2 | 2017-03-16 00:00:00 |   192 |     16 |    192
        2 | 2017-03-17 00:00:00 |   208 |     14 |    208
        2 | 2017-03-18 00:00:00 |   203 |     14 |    203
        2 | 2017-03-19 00:00:00 |   203 |     14 |    203
        2 | 2017-03-20 00:00:00 |    35 |      0 |     35
Run Code Online (Sandbox Code Playgroud)

如果我不使用,也会看到这种效果UNION

有一些显而易见的解决方法可以得到我想要的结果,但是这里的根本问题是,使用VARCHAR常量列而不是INTEGER常量列似乎在行为上存在直觉上的差异。

如果有人可以帮助我了解这种区别是什么,我将不胜感激。

Joh*_*ein 3

我想说您在 Amazon Redshift 中发现了一个真正的错误,或者至少是一种不受欢迎的行为。

我设法将范围缩小到:

  • 仅当 aVARCHAR用作 GROUP BY 之一时,并且
  • 使用多个COUNT(DISTINCT)语句时

所以,这个简单的语句也会产生太多的结果:

SELECT 
    '1',
    COUNT(DISTINCT user_source),
    COUNT(DISTINCT user_id)
FROM show_bug
GROUP BY 1
Run Code Online (Sandbox Code Playgroud)

但这没关系:

SELECT 
    '1'::INTEGER,
    COUNT(DISTINCT user_source),
    COUNT(DISTINCT user_id)
FROM show_bug
GROUP BY 1
Run Code Online (Sandbox Code Playgroud)

删除其中任何一个COUNT(DISTINCT)条目也可以使其正常工作。

如果您订阅了 AWS Support,我建议您提交错误报告。如果您没有订阅支持,您可以通过 AWS 支持论坛提交支持,但他们不保证响应时间。