【问题标题】:Update values in same table that reference different id更新同一表中引用不同 id 的值
【发布时间】:2019-11-15 13:29:38
【问题描述】:

我有一张表格,其中存储了不同商店的产品价格。 出口 A 有一个商品价格为 2 欧元的百事可乐,出口 B 以 2.50 欧元的价格出售百事可乐。现在我需要将所有商品的价格设置为彼此相等,这样 2 欧元应该变成 2.50。

我尝试了以下方法:

update PoscardOutlet_Default
set Poscard_Outlet_ItemPrice = (select Poscard_Outlet_ItemPrice
                                from PoscardOutlet_Default
                                where Poscard_Outlet_OutletPointer = 1)
where Poscard_Outlet_OutletPointer = 2

但我收到此错误:

消息 512,第 16 级,状态 1,第 2 行
子查询返回超过 1 个值。当子查询跟随 =、!=、、>= 或子查询用作表达式时,这是不允许的。声明已终止。

我希望奥特莱斯 2 中的所有商品与奥特莱斯 1 中的商品价格相同。

【问题讨论】:

  • 您的问题和您的查询彼此无关。 “产品”在哪里?过滤来自哪里?
  • 子查询需要关联,即包含引用主表的条件。 (主键的东西。)
  • 出口A中的百事可乐出口B中的百事必须有2列相关,每个表1,对吧?

标签: sql sql-server


【解决方案1】:

我会在这里使用可更新的 CTE:

WITH cte AS (
    SELECT
        t1.Poscard_Outlet_ItemPrice AS ItemPriceOld,
        t2.Poscard_Outlet_ItemPrice AS ItemPriceNew
    FROM PoscardOutlet_Default t1
    INNER JOIN PoscardOutlet_Default t2
        ON t1.ItemId = t2.ItemId
    WHERE
        t1.Poscard_Outlet_OutletPointer = 2 AND
        t2.Poscard_Outlet_OutletPointer = 1
)

UPDATE cte
SET ItemPriceOld = ItemPriceNew;

我在这里假设该表有一个名为ItemId 的主键列,没有它我们就无法真正编写任何查询。

【讨论】:

    【解决方案2】:

    现在我需要将所有商品的价格设置为彼此相等,这样 2 欧元应该变成 2.50。

    这个问题和你的代码关系不大。但要回答这个问题,请使用窗口函数和可更新的 CTE:

    with toupdate as (
          select pod.*,
                 max(Poscard_Outlet_ItemPrice) over (partition by product) as max_price
          from PoscardOutlet_Default
    update toupdate
        set Poscard_Outlet_ItemPrice = maxprice
        where Poscard_Outlet_ItemPrice <> maxprice or Poscard_Outlet_ItemPrice is null;
    

    如果您不想更新所有产品(尽管这似乎是您的要求),您当然可以添加适当的过滤。

    【讨论】:

      【解决方案3】:

      假设您有两个网点,但只有两种产品:

      Outlet   Product     Price
      1        Sweets      50p
      1        Drinks      60p
      2        Sweets      40p
      2        Drinks      55p
      

      就目前的情况而言,您的查询显示为“将插座 1 的所有价格设置为插座 2 的所有价格”......所以让我们开始手动操作:

      • Outlet 1 的第一个产品是“Sweets”,那么我们应该将其设置为什么价格?
      • 答案是“Outlet 2 的所有价格”,即 40 便士和 55 便士;
      • 但这是不可能的,我们如何将一个价格设置为两个不同的值?

      这基本上就是那个错误的意思Subquery returned more than one value

      您应该做的是只从 Outlet 2 中选择“Sweets”的价格,然后当您转到 Drinks 时,只从 Outlet 2 中选择“Drinks”的价格,等等。

      【讨论】:

      • 感谢您的澄清,这有助于我理解我做错了什么。我没有在查询中指定产品 ID。 Tim 的上述帖子解决了这个问题。
      【解决方案4】:

      这将在没有 CTE 的情况下工作

      更新 T1 设置 T1.Poscard_Outlet_ItemPrice = T2.Poscard_Outlet_ItemPrice FROM PoscardOutlet_Default t1 INNER JOIN PoscardOutlet_Default t2 开启 t1.ItemId = t2.ItemId 其中 T1.Poscard_Outlet_OutletPointer = 2 AND T2.Poscard_Outlet_OutletPointer = 1

      【讨论】:

        猜你喜欢
        • 2017-11-17
        • 2021-04-30
        • 2023-01-11
        • 2020-02-08
        • 1970-01-01
        • 1970-01-01
        • 2018-06-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多