【问题标题】:Selective update in SQL ServerSQL Server 中的选择性更新
【发布时间】:2013-01-10 13:41:16
【问题描述】:

我已经创建了一个像这样的连接表:

http://imageshack.us/scaled/landing/822/kantotype.png

我试图找出一个能够选择一些行的查询 - 基于PokémonID - 然后只更新主要“过滤”之后的第一行或第二行。

例如:

假设我想从包含PokémonID = 2 的第二行更改TypeID 的值。我不能简单地使用UPDATE KantoType SET TypeID = x WHERE PokémonID = 2,因为它会改变两行!

我已经尝试使用包含INEXISTSLIMIT 的子查询,但没有成功。

【问题讨论】:

  • 您需要提供有关 Pokemon 和 Type 表的信息,并解释为什么每个 Pokemon 在 KantoType 表中有两条记录。
  • 你不能在第二行做 WHERE PokemonID​​ = 2 AND TypeID = 18 吗?如果没有,你如何排列你的行——“第二”行是什么,“第一”行是什么?按 T​​ypeID 排序?
  • 其实很简单。如果你玩过神奇宝贝,你就会知道神奇宝贝可以有 1 或 2 种类型。但是,您可以注意到,在我提供的第一个表中,我为每个神奇宝贝添加了 2 种类型(注意:我们可以将 TypeID 视为没有第二种类型的默认值)。关于行的顺序,实际上没有一个:这完全取决于您正在考虑的神奇宝贝。例如,您可能有 2 个具有相同类型(例如钢和岩石)的神奇宝贝,但第一个神奇宝贝的主要类型可能是岩石,另一个是钢......
  • 其实我打算在C#项目中使用这个查询。以下是一些有用的链接:imageshack.us/photo/my-images/708/pokmonform.pngimageshack.us/scaled/landing/401/diagramf.png
  • 恐怕我还没玩过口袋妖怪。有两种选择。要么您知道要更新的类型,在这种情况下,您可以在查询中对 PokemonID​​ 和 TypeID 使用过滤器。或者如果您不知道 TypeID 但只是想更新“第二”行 - 那么您需要定义行的排序方式(例如,按 TypeID 升序/降序或其他列),这样您就可以告诉 SQL服务器哪一行是第二个。第二个选项的 SQL 由 Mahmoud Gamal 提供。

标签: sql sql-server select junction-table


【解决方案1】:

不清楚你想做什么。但是,您可以像这样使用UPDATEJOIN

UPDATE 
SET k1.TypeID = 'somethng' -- or some value from k2
FROM KantoType k1
INNER JOIN
(
   Some filtering and selecting
) k2 ON k1.PokémonID = k2.PokémonID 
WHERE k1.PokémonID = 2;

或者:如果您只想UPDATE 仅具有PokémonID = 2 的两行,您可以这样做:

WITH CTE
AS 
(
   SELECT *,
     ROW_NUMBER() OVER(ORDER BY TypeID) rownum
   FROM KantoType
   WHERE PokemonID = 2
) 
UPDATE c 
SET  c.TypeID = 5
FROM CTE c
WHERE c.rownum = 1;

SQL Fiddle Demo

【讨论】:

    【解决方案2】:

    如果您只需要更新表格中的一行,我可以建议您这样做:

    UPDATE kantotype
    SET 
      type = 2
    WHERE pokemon = 2
    AND NOT EXISTS (SELECT * FROM kantotype k2 
                    WHERE kantotype.type > k2.type
                       AND kantotype.pokemon = k2.pokemon)
    

    如果您的表格中有唯一标识符字段,则获取表格的第一项或最后一项会更容易。

    【讨论】:

      【解决方案3】:

      不确定即使您尝试通过对 TypeID 进行主要过滤来更新 PokemenID =2 的行...所以只是出于假设(大),您可以尝试一下在Case

      UPDATE yourtable a
      LEFT JOIN youtable b on a.pokeid = b.pokeid
      SET a.typeid = (CASE
         WHEN a.typeid < b.typeid THEN yourupdatevalue
         WHEN a.typeid > b.typeid THEN someothervalue   
         ELSE a.typeid END);
      

      【讨论】:

        【解决方案4】:

        如果您知道 pokemon ID 和类型 id,那么只需将两者都添加到查询的 where 子句中。

        UPDATE KantoType 
        SET TypeID = x 
        WHERE PokémonID = 2
        AND TypeID=1
        

        如果您不知道类型 ID,则需要提供有关您要完成的任务的更多信息。目前尚不清楚您为什么没有此信息。

        也许考虑一下数据集中的唯一标识符是什么。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-12-01
          • 1970-01-01
          • 1970-01-01
          • 2021-09-25
          • 1970-01-01
          相关资源
          最近更新 更多