Snowflake cloud data platform /代码>这可以转换为限定,并且可以跳过层

Snowflake cloud data platform /代码>这可以转换为限定,并且可以跳过层,snowflake-cloud-data-platform,Snowflake Cloud Data Platform,主要有两件事,如何转换SQL,以及如何避免被腐蚀的子查询 首先,联接中的三个子选择具有相同的模式,因此我们将讨论第一个子选择,其中rownum=1可以通过limit 1顺序通过QUALIFY完成,我更喜欢后者 SELECT to_char(cliterm.Quantity) FROM ContractLineItemTerm cliterm WHERE cliterm.ContractLineItem_id = cli.Id AND ( cliterm.EndDate I

主要有两件事,如何转换SQL,以及如何避免被腐蚀的子查询

首先,联接中的三个子选择具有相同的模式,因此我们将讨论第一个子选择,
其中rownum=1
可以通过
limit 1
顺序通过
QUALIFY
完成,我更喜欢后者

SELECT to_char(cliterm.Quantity)
FROM ContractLineItemTerm cliterm
WHERE cliterm.ContractLineItem_id = cli.Id
    AND (
        cliterm.EndDate IS NULL
        OR cliterm.EndDate > add_months(sysdate, - 3)
        )
    AND cliterm.PriceRuleItem_id IS NULL
QUALIFY row_numumber() OVER (ORDER BY cli.id DESC) = 1
然后,当您在corrolated子查询中使用它时,它实际上也是随机的,因为您是按
cli.id
排序的,但也加入了同一个子句,因此实际上您没有对数据进行排序。因此,首先,您需要有一个更好的子句来从
ContractLineItemTerm
中进行选择,我将创建一个名为
is\u best
的列,这样SQL才有意义,然后您可以在其中放入一些有意义的内容

接下来要注意的是,您的四个选择都是相同的SQL块,因此我们可以将其更改为一个连接,并使用它来完成

所以我使用了一个CTE,这样你就可以看到四个块是如何作为一个块写入的,并且重新格式化了你的
JOIN
,使之在新的行上,对于更复杂的SQL来说,它更好,我将你的
CASE
重写为
IFF
,因为它是一个简单的两分支CASE

WITH best_per_id (
    SELECT cliterm.ContractLineItem_id
        ,to_char(cliterm.Quantity) as Quantity
        ,cliterm.UsedQuantity
        ,cliterm.StartDate
    FROM ContractLineItemTerm cliterm
    WHERE cliterm.PriceRuleItem_id IS NULL
        AND (
            cliterm.EndDate IS NULL
            OR cliterm.EndDate > add_months(sysdate, - 3)
            )
    QUALIFY row_numumber() OVER (PARTITION BY cliterm.ContractLineItem_id 
        ORDER BY cliterm.is_best ) = 1
)
SELECT DISTINCT cust.Id AS Customer_Id
    ,nvl(bpi.Quantity, cli.Quantity) AS Quantity_Purchased
    ,nvl(bpi.UsedQuantity, cli.UsedQuantity) AS Quantity_Used_To_Date
    ,nvl(bpi.StartDate, cli.StartDate) AS sbscription_Term_Start_Date
    ,nvl(bpi.EndDate, cli.EndDate) AS sbscription_Term_End_Date
    ,nvl(to_char(cli.EndDate), 
         IFF(cli.StartDate IS NOT NULL AND con.InitialTerm > 0, 'Auto Renewal', '')
        ) AS Contr_End_Date
FROM ContractLineItem cli
INNER JOIN Contract con 
    ON cli.Contract_id = con.Id
INNER JOIN Customer cust 
    ON con.Customer_id = cust.Id
INNER JOIN Organization org 
    ON org.Customer_id = cust.Id
INNER JOIN Product prod 
    ON cli.Product_id = prod.Id
INNER JOIN Producttype pt 
    ON prod.ProductBrand_id = pt.Id
LEFT JOIN best_per_id as bpi
    ON cli.id = bpi.ContractLineItem_id
LEFT JOIN account acc 
    ON cust.SAN = acc.acc__c
LEFT JOIN account acc1 
    ON acc.parentid = acc1.id
LEFT JOIN sbSCRIPTION sb 
    ON sb.id = cli.sforceid
LEFT JOIN sbSCRIPTION pasb 
    ON pasb.id = sb.srequired
LEFT JOIN scontract1 cntr 
    ON cntr.contractnumber = con.ContNumber
LEFT JOIN user accowner 
    ON acc.ownerid = accowner.id
LEFT JOIN user accsalesmanager 
    ON accowner.managerid = accsalesmanager.id
LEFT JOIN (
    SELECT f.accountid
        ,g.managerid
        ,max(g.NAME) CSM
        ,max(g.id) CSMID
    FROM accountteammember f
    JOIN user g ON f.userid = g.id
    WHERE f.teammemberrole = 'AGM'
    GROUP BY f.accountid
        ,g.managerid
    ) acccsm ON acccsm.accountid = acc.id
LEFT JOIN product2 prd 
    ON prod.Code = prd.productcode
LEFT JOIN prdfam prod_fam 
    ON prod_fam.product_family_desc = prd.Product_Family__c
QUALIFY Quantity_Purchased <> 0;

请编辑您的问题以包含完整的SQL语句;您不需要在SELECT中提供所有列,但需要包括所有表及其联接逻辑。我提到了完整的oracle sql查询,现在需要根据Snowflake进行更改。请建议更改。您好-每个子选择中的ORDER BY cli.id不会起任何作用,因为选择仅限于一个id(来自连接)。如果这些子选择返回多个记录,那么您将得到一个随机选择-我假设这不是您想要的。对于每个cli.id,如果有多个记录,那么确定从每个子选择返回哪个记录的正确逻辑是什么?
WITH best_per_id (
    SELECT cliterm.ContractLineItem_id
        ,to_char(cliterm.Quantity) as Quantity
        ,cliterm.UsedQuantity
        ,cliterm.StartDate
    FROM ContractLineItemTerm cliterm
    WHERE cliterm.PriceRuleItem_id IS NULL
        AND (
            cliterm.EndDate IS NULL
            OR cliterm.EndDate > add_months(sysdate, - 3)
            )
    QUALIFY row_numumber() OVER (PARTITION BY cliterm.ContractLineItem_id 
       ORDER BY cliterm.is_best ) = 1
)
SELECT DISTINCT cust.Id AS Customer_Id
    ,nvl(bpi.Quantity, cli.Quantity) AS Quantity_Purchased
    ,nvl(bpi.UsedQuantity, cli.UsedQuantity) AS Quantity_Used_To_Date
    ,nvl(bpi.StartDate, cli.StartDate) AS sbscription_Term_Start_Date
    ,nvl(bpi.EndDate, cli.EndDate) AS sbscription_Term_End_Date
    ,nvl(to_char(cli.EndDate), 
         IFF(cli.StartDate IS NOT NULL AND con.InitialTerm > 0, 'Auto Renewal', '')
        ) AS Contr_End_Date
FROM ContractLineItem cli
INNER JOIN Contract con 
    ON cli.Contract_id = con.Id
INNER JOIN Customer cust 
    ON con.Customer_id = cust.Id
INNER JOIN Organization org 
    ON org.Customer_id = cust.Id
INNER JOIN Product prod 
    ON cli.Product_id = prod.Id
INNER JOIN Producttype pt 
    ON prod.ProductBrand_id = pt.Id
LEFT JOIN (
    SELECT cliterm.ContractLineItem_id
        ,to_char(cliterm.Quantity) as Quantity
        ,cliterm.UsedQuantity
        ,cliterm.StartDate
    FROM ContractLineItemTerm cliterm
    WHERE cliterm.PriceRuleItem_id IS NULL
        AND (
            cliterm.EndDate IS NULL
            OR cliterm.EndDate > add_months(sysdate, - 3)
            )
    QUALIFY row_numumber() OVER (PARTITION BY cliterm.ContractLineItem_id ORDER BY cliterm.is_best ) = 1
) as bpi
    ON cli.id = bpi.ContractLineItem_id
LEFT JOIN account acc 
    ON cust.SAN = acc.acc__c
LEFT JOIN account acc1 
    ON acc.parentid = acc1.id
LEFT JOIN sbSCRIPTION sb 
    ON sb.id = cli.sforceid
LEFT JOIN sbSCRIPTION pasb 
    ON pasb.id = sb.srequired
LEFT JOIN scontract1 cntr 
    ON cntr.contractnumber = con.ContNumber
LEFT JOIN user accowner 
    ON acc.ownerid = accowner.id
LEFT JOIN user accsalesmanager 
    ON accowner.managerid = accsalesmanager.id
LEFT JOIN (
    SELECT f.accountid
        ,g.managerid
        ,max(g.NAME) CSM
        ,max(g.id) CSMID
    FROM accountteammember f
    JOIN user g ON f.userid = g.id
    WHERE f.teammemberrole = 'AGM'
    GROUP BY f.accountid
        ,g.managerid
    ) acccsm ON acccsm.accountid = acc.id
LEFT JOIN product2 prd 
    ON prod.Code = prd.productcode
LEFT JOIN prdfam prod_fam 
    ON prod_fam.product_family_desc = prd.Product_Family__c
QUALIFY Quantity_Purchased <> 0;