雪花子查询

时间:2016-12-21 13:39:46

标签: sql database postgresql snowflake snowflake-datawarehouse

我有两张桌子。 交易(ID,TERMINALID)和终端(ID,TERMINALID,EXPORT_DATE)。目标是从终端表中最新记录的 Transaction 表获取每一行。雪花用作后端。

我有这个SQL查询:

SELECT tr.ID,
       (SELECT te.ID
        FROM "Terminal" te
        WHERE te.TERMINALID = tr.TERMINALID
        ORDER BY te.EXPORT_DATE DESC
        LIMIT 1)
FROM "Transaction" tr;

但是我收到了这个错误:

  

SQL编译错误:无法评估不支持的子查询类型

如果我用特定值替换 tr.TERMINALID ,则错误消失。所以我不能从嵌套的SELECT引用父表。为什么这不可能?查询适用于MySQL。

2 个答案:

答案 0 :(得分:7)

我担心Snowflake不支持此类相关子查询。

您可以使用FIRST_VALUE计算最佳的每终端ID:

来实现您的目标
-- First compute per-terminalid best id
with sub1 as (
  select 
    terminalid, 
    first_value(id) over (partition by terminalid order by d desc) id
  from terminal 
),
-- Now, make sure there's only one per terminalid id
sub2 as (
  select 
    terminalid, 
    any_value(id) id
  from sub1
  group by terminalid
)
-- Now use that result
select tr.ID, sub2.id
FROM "Transaction" tr
JOIN sub2 ON tr.terminalid = sub2.terminalid

您可以先运行子查询,看看他们做了什么。

我们正在努力更好地支持子查询,并且可能有更简单的重写,但我希望它有所帮助。

答案 1 :(得分:0)

SELECT
tr.ID
  , (SELECT te.ID
     FROM "Terminal" te 
     WHERE te.TERMINALID = tr.TERMINALID
     ORDER BY te.EXPORT_DATE DESC
     LIMIT 1
    ) AS the_id -- <<-- add an alias for the column
FROM "Transaction" tr
    ;

更新:

  • length for type varchar cannot exceed 10485760
  • 只需使用类型varchar(或text

在这里工作(带引号标识符):

CREATE TABLE "Transaction" ("ID" VARCHAR(123), "TERMINALID"  VARCHAR(123)) ;
CREATE TABLE "Terminal" ( "ID"  VARCHAR(123), "TERMINALID"  VARCHAR(123), "EXPORT_DATE" DATE);

SELECT tr."ID"
        , (SELECT te."ID"
        FROM "Terminal" te
        WHERE te."TERMINALID" = tr."TERMINALID"
        ORDER BY te."EXPORT_DATE" DESC
        LIMIT 1) AS meuk
FROM "Transaction" tr
        ;

BONUS UPDATE:避免使用标量子查询并使用普通旧NOT EXISTS(...)来获取具有最新日期的记录:

SELECT tr."ID"
        , te."ID" AS meuk
FROM "Transaction" tr
JOIN "Terminal" te ON te."TERMINALID" = tr."TERMINALID"
        AND NOT EXISTS ( SELECT *
        FROM "Terminal" nx
        WHERE nx."TERMINALID" = te."TERMINALID"
        AND nx."EXPORT_DATE" > te."EXPORT_DATE"
        )
        ;