【问题标题】:Execute select query in where condition在where条件下执行选择查询
【发布时间】:2020-08-29 05:15:22
【问题描述】:

我想根据 SQL Server 中的用户帐户在 where 条件中执行选择查询,以更新表以填充数字增量。

这是我的代码:

DECLARE @i INT = 0;
WHILE @i <= 1077
begin   
    update tbl_UdharKhata set ReceiptNo = @i 
    where EXISTS (select distinct UserId from tbl_udharkhata)
    SET @i = @i + 1;    
end

此查询运行良好,但问题是在ReceiptNo 整个用户帐户收据编号更新相同的编号。

注意:有 1077 行不同的用户帐户,因此有 1077 行用户 ID。

【问题讨论】:

  • 您似乎要更新表中的 1077 条记录。您能否清楚地阐明哪些 1077 条记录应该得到更新的逻辑?
  • edit您的问题包括proper示例数据和预期结果。

标签: sql-server database while-loop increment sql-query-store


【解决方案1】:

您所做的是更新表中的所有记录 1077 次,每次使用不同的数字,直到循环结束。现在我不确定您是否需要为每个 userId 提供一个数字,或者为具有相同 userId 的每一行提供一个递增数字,每个 userId 从 1 开始。

SELECT 语句不返回任何内容的唯一方法是表为空 - 因为它没有 WHERE 子句。
由于您的select 语句位于EXISTS 运算符中,因此条件将始终计算为true,从而使UPDATE 语句的WHERE 子句变得多余。

基本上,就像update tbl_UdharKhata set ReceiptNo = @i where exists(select 1), 这就像update tbl_UdharKhata set ReceiptNo = @i

这意味着在循环的每次迭代中,您将使用当前值@i 更新表中的所有记录。

现在,你的问题不是很清楚你想要什么,但我会在这里冒个险,猜你想更新ReceiptNo 列,这样对于每个userId,你都会有一个递增的编号,每个新用户 ID 重置为 1。
如果是这种情况,最简单的方法是创建一个公用表表达式 (cte),然后更新该 cte:

;WITH cte AS
(
    SELECT ReceiptNo
           -- Note: Order by @@SPID means an arbitrary order! Details after the code.
         , ROW_NUMBER() OVER(PARTITION BY UserId ORDER BY @@SPID) As Rn
    FROM tbl_UdharKhata 
)

UPDATE cte
SET ReceiptNo = Rn

注意我在ROW_NUMBER()OVER 子句中使用了ORDER BY @@SPID

@@SPID 是一个内置函数,它返回当前用户进程的会话 ID - 这意味着它将在每个会话中返回一个常量值。
使用带有常量值的Order by 将生成任意顺序。

如果您需要特定的顺序,请使用表中不是 userId 的任何列(否则您最终会得到相同的任意顺序 - 因为每个分区的 userId 将是相同的)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-12-09
    • 2016-01-23
    • 1970-01-01
    • 1970-01-01
    • 2018-06-18
    • 1970-01-01
    • 2018-03-26
    • 1970-01-01
    相关资源
    最近更新 更多