SQL Server 中的选择性更新

Posted

技术标签:

【中文标题】SQL Server 中的选择性更新【英文标题】:Selective update in SQL 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 提供。 【参考方案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,则需要提供有关您要完成的任务的更多信息。目前尚不清楚您为什么没有此信息。

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

【讨论】:

以上是关于SQL Server 中的选择性更新的主要内容,如果未能解决你的问题,请参考以下文章

保存选择查询中的值,然后在更新查询 SQL Server CE 中使用它们

怎样设置sql server2012中的订阅

如果存储过程在 SQL Server 2005 上的选择之前进行更新,则没有结果集

SQL SERVER的统计信息

从 sql server 获取选定的值到 php 中的下拉列表

SQL Server 2014 优化器索引选择性