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
,因为它会改变两行!
我已经尝试使用包含IN
、EXISTS
和LIMIT
的子查询,但没有成功。
【问题讨论】:
您需要提供有关 Pokemon 和 Type 表的信息,并解释为什么每个 Pokemon 在 KantoType 表中有两条记录。 你不能在第二行做 WHERE PokemonID = 2 AND TypeID = 18 吗?如果没有,你如何排列你的行——“第二”行是什么,“第一”行是什么?按 TypeID 排序? 其实很简单。如果你玩过神奇宝贝,你就会知道神奇宝贝可以有 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】:不清楚你想做什么。但是,您可以像这样使用UPDATE
和JOIN
:
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 Server 2005 上的选择之前进行更新,则没有结果集