在SQL Server 2008中领先

时间:2018-02-28 16:18:27

标签: sql sql-server sql-server-2008 window-functions

我已经完成了包含LEAD的存储过程,遗憾的是该脚本必须在2008年运行,所以任何人都知道如何在2008年实现这一目标?

INSERT INTO #ARTICLES(EAN, ID_ART, QTE, PV_NET_HT)
SELECT EAN, ID_ART, QTE_CDE, PA_NET
FROM (
    SELECT TEXTE_LIG,
            CASE WHEN TEXTE_LIG LIKE '%++%' THEN ID_ART ELSE LEAD(ID_ART) OVER (ORDER BY (SELECT NULL)) END AS ID_ART,
            CASE WHEN TEXTE_LIG LIKE '%++%' THEN CHAR01 ELSE LEAD(CHAR01) OVER (ORDER BY (SELECT NULL)) END AS EAN,
            LEAD(QTE_CDE, CASE WHEN TEXTE_LIG LIKE '%++%' THEN 1 ELSE 2 END) OVER (ORDER BY (SELECT NULL)) AS QTE_CDE,
            LEAD(PX_BASE, CASE WHEN TEXTE_LIG LIKE '%++%' THEN 2 ELSE 3 END, NULL) OVER (ORDER BY (SELECT NULL)) AS PX_BASE,
            LEAD(PX_NET, CASE WHEN TEXTE_LIG LIKE '%++%' THEN 2 ELSE 3 END, NULL) OVER (ORDER BY (SELECT NULL)) AS PA_NET
    FROM AMAZON_ACHATS_LIG 
    WHERE ID_ACHATS_ENT = @IDENTITY
) AS LIGNE
WHERE TEXTE_LIG LIKE 'LIN%';

1 个答案:

答案 0 :(得分:2)

要在2008年替换LEAD,您需要对同一个表进行自我连接,直到下一行。要做到这一点,最简单的方法是拥有某种类型的连续ID,并且可以使用ID + 1连接到记录。如果不存在合适的连续ID,则在CTE中选择数据,并为其添加row_number。然后在外部查询中使用该row_number进行自联接。

顺便说一句,请注意,没有"保持数据库顺序"。如果您没有为给定查询指定订单,则SQL将决定输出顺序,该顺序可能与条目的顺序相同,或者可能是完全不同的顺序,或者可能大致相同的顺序除外几条记录。它可能会在不同的场合为同一查询返回完全不同的订单,具体取决于它此次决定使用的查询计划。如果您希望数据保持与输入的顺序相同,则需要具有自动递增标识列以确保可能,或者有一天您将无法获得预期。

在您的查询中,您的各种潜在客户的偏移量均为无(1),1,2和3,因此您需要自行加入三次才能涵盖所有这些选项。在查询中,然后将每个LEAD替换为正确的自联接表中的数据。你想要这样的东西:

WITH BASEDATA AS (
    --THIS IS YOUR BASIC DATA, WITH A ROW NUMBER ADDED
    -- DO THIS AS A CTE, SO YOU CAN JOIN TO IT MULTIPLE TIMES
    SELECT TEXTE_LIG, ID_ART, CHAR01, QTE_CDE, PX_BASE, PX_NET, ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS RowNo
    FROM AMAZON_ACHATS_LIG 
    WHERE ID_ACHATS_ENT = @IDENTITY
)
INSERT INTO #ARTICLES(EAN, ID_ART, QTE, PV_NET_HT)
SELECT EAN, ID_ART, QTE_CDE, PA_NET
FROM (
    SELECT TEXTE_LIG,
            CASE WHEN TEXTE_LIG LIKE '%++%' THEN ID_ART ELSE B1.ID_ART END AS ID_ART,
            CASE WHEN TEXTE_LIG LIKE '%++%' THEN CHAR01 ELSE B1.CHAR01 END AS EAN,
            CASE WHEN TEXTE_LIG LIKE '%++%' THEN B1.QTE_CDE ELSE B2.QTE_CDE END AS QTE_CDE,
            CASE WHEN TEXTE_LIG LIKE '%++%' THEN B2.PX_BASE ELSE B3.PX_BASE END AS PX_BASE,
            CASE WHEN TEXTE_LIG LIKE '%++%' THEN B2.PX_NET ELSE B3.PX_NET END AS PA_NET
    FROM BASEDATA B0  --THE BASIC DATA
        LEFT OUTER JOIN BASEDATA B1 ON B1.RowNo = B0.RowNo + 1  --This is your LEAD (1) table
        LEFT OUTER JOIN BASEDATA B2 ON B2.RowNo = B0.RowNo + 2  --This is your LEAD (2) table
        LEFT OUTER JOIN BASEDATA B3 ON B3.RowNo = B0.RowNo + 3  --This is your LEAD (3) table
    --WHERE ID_ACHATS_ENT = @IDENTITY  --DON'T NEED THIS AMY MORE, DONE IN CTE
) AS LIGNE
WHERE TEXTE_LIG LIKE 'LIN%';