【问题标题】:SQL Server UPDATE based on previous dateSQL Server UPDATE 基于上一个日期
【发布时间】:2024-01-17 21:34:01
【问题描述】:

这是关于每天从网络上获取的一些客户 (custID) 的产品列表 (prodID)。 问题是有时当产品不可用时,页面会重定向到类似的产品,我们最终会获取错误的信息。所以 custID 和 prodID 是正确的,但价格、卖方和标题是错误的。正确的标题在 masterTitle 列中。

我需要将错误的行标记为 notAvailable = 1。

请注意,在某些情况下,与 masterTitle 相比,标题是不同的,但这是有效的,因为它可能是一个简单的标题重命名。 例如 350 毫升 - 产品 01 = 产品 01 - 350 毫升。

我对 C# 很熟悉,但我更喜欢使用 T-SQL。 按照我的想象,我需要将每个 custID/prodID 的每一天与前一个“最后一个好日子”(最后一个日期具有有效数据)进行比较。

伪代码。对于每条记录:

If title = masterTitle then 
{
Keep current values (title, price, seller) as lastGoodValues
}
else
If lastGoodValues.price <> nextDay.price AND lastGoodValues.seller <> nextDay.seller
{
notAvailable = 1
}
move to the next record/day

所以,我有这个:

ReportDate | custID | prodID | price |  sellers |        title          | masterTitle         | notAvail
-----------+--------+--------+-------+----------+-----------------------+---------------------+---------
16/04/2020 | 266    | 191750 | 15.59 | Seller01 | Product 01 - 350 ml   | Product 01 - 350 ml | 0
17/04/2020 | 266    | 191750 | 15.59 | Seller01 | 350 ml - Product 01   | Product 01 - 350 ml | 0
18/04/2020 | 266    | 191750 |    18 | Seller02 | Procuct 02 - 1 Litres | Product 01 - 350 ml | 0
19/04/2020 | 266    | 191750 |    18 | Seller02 | Procuct 02 - 1 Litres | Product 01 - 350 ml | 0
20/04/2020 | 266    | 191750 | 15.59 | Seller01 | Product 01 - 350 ml   | Product 01 - 350 ml | 0
21/04/2020 | 266    | 191750 |    18 | Seller01 | Procuct 02 - 1 Litres | Product 01 - 350 ml | 0
22/04/2020 | 266    | 191750 | 15.59 | Seller01 | Product 01 - 350 ml   | Product 01 - 350 ml | 0
18/04/2020 | 301    |    565 |     5 | Seller Y | Procuct Y             | Product X           | 0
19/04/2020 | 301    |    565 |     8 | Seller X | Product - X           | Product X           | 0
20/04/2020 | 301    |    565 |     8 | Seller X | Product X             | Product X           | 0
21/04/2020 | 301    |    565 |     5 | Seller Y | Procuct Y             | Product X           | 0
22/04/2020 | 301    |    565 |     8 | Seller X | Product X             | Product X           | 0

...我需要这个(见最后一栏 - notAvail):

ReportDate | custID | prodID | price |  sellers |        title          | masterTitle         | notAvail
-----------+--------+--------+-------+----------+-----------------------+---------------------+---------
16/04/2020 | 266    | 191750 | 15.59 | Seller01 | Product 01 - 350 ml   | Product 01 - 350 ml | 0
17/04/2020 | 266    | 191750 | 15.59 | Seller01 | 350 ml - Product 01   | Product 01 - 350 ml | 0
18/04/2020 | 266    | 191750 |    18 | Seller02 | Procuct 02 - 1 Litres | Product 01 - 350 ml | 1
19/04/2020 | 266    | 191750 |    18 | Seller02 | Procuct 02 - 1 Litres | Product 01 - 350 ml | 1
20/04/2020 | 266    | 191750 | 15.59 | Seller01 | Product 01 - 350 ml   | Product 01 - 350 ml | 0
21/04/2020 | 266    | 191750 |    18 | Seller01 | Procuct 02 - 1 Litres | Product 01 - 350 ml | 1
22/04/2020 | 266    | 191750 | 15.59 | Seller01 | Product 01 - 350 ml   | Product 01 - 350 ml | 0
18/04/2020 | 301    |    565 |     5 | Seller Y | Procuct Y             | Product X           | 1
19/04/2020 | 301    |    565 |     8 | Seller X | Product - X           | Product X           | 0
20/04/2020 | 301    |    565 |     8 | Seller X | Product X             | Product X           | 0
21/04/2020 | 301    |    565 |     5 | Seller Y | Procuct Y             | Product X           | 1
22/04/2020 | 301    |    565 |     8 | Seller X | Product X             | Product X           | 0

【问题讨论】:

  • 您的问题具体是什么?这不是“我需要”或“我想像它”。也许如何直觉不同的字符串足够接近以匹配我的目的?
  • HABO,感谢您的回复。如上所述,我的具体问题是:我需要将错误的行标记为 notAvailable = 1。我想该方法将类似于附加的伪代码,但在不知道 T-SQL 的细节的情况下,我无法确定。 “我需要”指的是我需要这个……
  • 您提供了一个模糊的需求文档,而不是一个具体的问题。我是否应该猜测以下是等效的:“产品 01”、“产品 1”、“产品 001”、“产品 01”、“产品 0-1”? “500ml”、“0.5l”、“0.5 升”、“500.ml”、“0.5 升”怎么样?任何对以任何顺序与任何分隔符组合?添加一点代码来处理“Procuct Y”[sic] 作为特例?您的伪代码遗漏了一些标题匹配细节。
  • 根据描述:custID、prodID 和 masterTitle (总是)正确。卖家、价格和标题字段可能有误。您无需猜测任何内容。问题非常具体,它是:如何标记错误的行(notAvailable - 1)。伪代码只是一个起点。我不会再回复你,因为你显然只是想争论而不是提供建议/解决方案。

标签: sql-server tsql date sql-update


【解决方案1】:

如果您有另一个名为 lastGoodValues 的表,您可以尝试这样的操作(未经测试):

MERGE INTO LastGoodValues L
USING (
    SELECT * FROM YourTable
    WHERE title=masterTitle
) T ON L.title=T.title
WHEN MATCHED THEN UPDATE SET price=T.price, seller=T.seller
WHEN NOT MATCHED THEN INSERT (title, price, seller) VALUES (T.title, T.price, T.seller);

UPDATE YourTable SET notAvailable=1
FROM YourTable T
INNER JOIN LastGoodValues L ON L.title=T.title
WHERE T.title<>T.masterTitle
AND L.price<>T.price AND L.seller<>T.seller

【讨论】:

    【解决方案2】:

    感谢拉兹南。它进行了一些小的修改: 小提琴可用here

    MERGE INTO @LastGoodValues L
    USING (
        SELECT * FROM @YourTable
        WHERE title=masterTitle
    ) T ON L.title=T.title
    WHEN MATCHED THEN UPDATE SET reportDate = T.reportDate, custID = T.custID, prodID = T.prodID, price=T.price, seller=T.seller
    WHEN NOT MATCHED THEN INSERT (reportDate, custID, prodID, title, price, seller) VALUES (T.reportDate, T.custID, T.prodID, T.title, T.price, T.seller);
    
    
    UPDATE @YourTable SET notAvailable=1
    FROM @YourTable T
    INNER JOIN @LastGoodValues L ON L.custID=T.custID and L.prodID = T.prodID
    WHERE T.title<>T.masterTitle
    AND L.price<>T.price AND L.seller<>T.seller
    

    【讨论】: