【问题标题】:Subquery in Snowflake select clause not evaluating row by row?雪花选择子句中的子查询不逐行评估?
【发布时间】:2019-09-23 23:36:09
【问题描述】:

我正在尝试编写一个非常简单的查询:我想提取雪花表中的所有帐户,并标记可以链接到机会表中记录的帐户(真/假),并在输入字段。

这是一个我认为会返回我正在寻找的内容的查询:

SELECT
    acc.id
    , acc.id IN (
        SELECT DISTINCT(opp.accountid)
        FROM "OPPORTUNITY" opp
        WHERE opp.type LIKE '%Startup%'
        ) AS startup
FROM "ACCOUNT" acc

帐户表有大约 100,000 个不同的记录,子查询返回一个仅包含大约 11,000 个不同帐户 ID 的列表,但别名为“startup”的字段对于每个帐户都包含 TRUE。我已经尝试诊断为什么这会返回所有 True 而没有运气。我还尝试使用带有相关子查询的 EXISTS 编写相同的查询,并得到了相同的结果。

我能够通过在 FROM 子句之后加入子查询来构建一个工作查询,但我很想了解为什么上面的查询无法正确评估每一行。

任何帮助将不胜感激。谢谢!

【问题讨论】:

    标签: sql subquery correlated-subquery snowflake-cloud-data-platform


    【解决方案1】:

    我无法重现您看到的行为:

    create or replace table ACCOUNT(id int);
    insert into ACCOUNT values (1), (2), (3);
    create or replace table OPPORTUNITY(accountid int, type varchar);
    insert into OPPORTUNITY values (1, 'Startup'), (2, 'Startup');
    

    在上面运行您的查询然后产生结果:

    Row   ID   STARTUP
    1     1    TRUE
    2     2    TRUE
    3     3    FALSE
    

    【讨论】:

    • 感谢您的回复!很奇怪吧?我在其他查询中使用了几乎相同的逻辑,以前从未遇到过问题。我已经让几个同事看看这个问题,它让每个人都感到难过。还有其他想法吗?
    【解决方案2】:

    看看这两个查询的结果对我们来说会很有趣:

    SELECT COUNT(DISTINCT accountid)
    FROM   opportunity
    WHERE  type LIKE '%Startup%';
    
    
    SELECT COUNT(DISTINCT accountid)
    FROM   opportunity
    WHERE  type iLike '%Startup%';
    

    我认为以下内容可能是您的最终目标:

    SELECT acc.id,
           startup.accountid
    FROM   ACCOUNT acc
    LEFT OUTER JOIN (
        SELECT COUNT(DISTINCT accountid) as accountid
        FROM   opportunity
        WHERE  type iLike '%Startup%'
        AND    accountid IS NOT NULL) startup 
    ON acc.id = startup.accountid;
    

    **** 开始附加信息 ****

    在阅读了 cmets 之后,我决定多玩一点,果然我的测试正在工作,也许你有空值或类似的东西弄乱了你的数据或结果?我不确定,但这对我有用!

    create table account (id varchar);
    insert into account values ('A'), ('B'),('C'),('D');
    
    create table opportunity (accountid varchar, type varchar);
    insert into opportunity values ('D', 'New Subscription'), ('X', 'Stuff'), ('Y', 'Stuff'), ('Z', 'Stuff');
    
    select account.id,
           account.id in (select distinct accountid FROM opportunity WHERE type like '%Subscr%') as startup
    FROM   account;
    
    ID  STARTUP
    A   FALSE
    B   FALSE
    C   FALSE
    D   TRUE
    

    【讨论】:

    • 感谢您的回复!上面的两个查询都返回了相同的数量(~11k)。并感谢左连接的第二个查询。它确实按预期工作(我现在将其用作解决方案),但我仍然很想弄清楚原始查询中可能出现的问题 - 还有其他想法吗?
    • 您能否分享一小部分(2-3 行)来自 OPPORTUNITY 和 ACCOUNT 的示例值,它们为 IN 测试提供“真”,而它们应该提供假?我想尝试创建一个反映表中实际值的小型可复制集...
    • 嘿斯图尔特,当然。这是我正在查询的数据的一小部分: ACCOUNT {id: 'A'} {id: 'B'} {id: 'C'} {id: 'D'} OPPORTUNITY {accountid: 'A', type : 'New Subscription'} {accountid: 'B', type: 'New Subscription - Startup'} {accountid: 'D', type: 'New Subscription'} 我原始帖子中的查询对所有帐户都返回 TRUE,但我'正在尝试仅将帐户 'B' 标记为 TRUE
    • 当 ACCOUNT 和 OPPORTUNITY 表使用 VARIANT 类型时,我得到了同样的错误结果,但在使用完全结构化的列时却没有——所以我会报告一个错误。
    • 有趣的是,表中的所有值(acc.id、opp.account、opp.type)都存储为 VARCHAR。您是说您在完全结构化的列方面取得了成功?
    猜你喜欢
    • 1970-01-01
    • 2020-02-02
    • 1970-01-01
    • 1970-01-01
    • 2023-02-24
    • 1970-01-01
    • 2010-10-03
    • 1970-01-01
    相关资源
    最近更新 更多