【问题标题】:How to set value to variable in select query in SQL Server 2012?如何在 SQL Server 2012 的选择查询中为变量设置值?
【发布时间】:2015-10-12 13:59:44
【问题描述】:

我想为一个复杂的查询生成一个序列。为此,我使用了变量@rowNo

我的逻辑是:- 如果一个字段 - isremoved = 0 则将行号增加 1。
如果isremoved = 1 则只将行号增加一次,直到找到下一个 0。

到目前为止我已经完成了,但它给了我语法错误。

DECLARE @rowNo INT;
SET @rowNo = -1;

SELECT
case when sampleTable.isremoved = 0 then @rowNo + 1
    else @rowNo end
as rowNumber,
X,
Y,
Z
.
.
FROM tbl_sample sampleTable
INNER JOIN tbl_sample_2 sample2 ON sampleTable.id = sample2.id
.
.
.

这是我想要的输出:-

那么在sql server 2012 中实现这种功能的正确方法是什么?

编辑:- 我确实有一种使用子查询来检索行号的解决方案。但这会影响性能,因为它是具有大量数据的非常复杂的查询(超过 20 个连接)。 所以请给我一个替代方案。

【问题讨论】:

标签: sql variables sql-server-2012 setvalue


【解决方案1】:

在 SQL Server 2012+ 中,您可以使用累积和来做您想做的事情:

SELECT sum(case when sampleTable.isremoved = 0 then 1 else 0 end) over
            (order by . . .)
       . . .

order by 应该在外部查询中重复 order by。您也可以尝试使用order by (select null))。以我的经验,这使用了外部查询中数据的顺序,但这并没有记录到始终有效。

SQL Server 不允许您在 SELECT 中设置变量并在结果集中返回值。一种或另一种,但不能两者兼而有之。

【讨论】:

    【解决方案2】:

    一种方法是使用子查询:

    Select (Select count(*) from tbl_sample
            where id <= a.id 
                and a.isRemoved =1) rowNumber,
       X, Y, Z
    From tbl_sample a
         Join tbl_sample_2 b 
             On b.id = a.id
    

    【讨论】:

    • 这是一个非常复杂的查询(几乎 20 个连接)。所以这种解决方案会影响性能。
    • 是的,它会,但是,假设其中一个 id 列是外键,如果你在上面放一个索引,这将最大限度地减少性能损失。
    【解决方案3】:

    我假设您的 rowNumber 逻辑相当于:如果之前的 isremoved = 0 则将 rowNumber 增加 1,否则保持原样。

    使用LAGSUM ... OVER 的组合可以轻松实现这个逻辑:

    SELECT id, isremoved,
           SUM(IIF(prevFlag = 0, 1, 0)) OVER (ORDER BY id) AS rowNumber
    FROM (
    SELECT a.id, isremoved,
           COALESCE(LAG(isremoved) OVER (ORDER BY a.id), isremoved) AS prevFlag
    FROM tbl_sample AS a
    INNER JOIN tbl_sample_2 AS b ON b.id = a.id) AS t
    

    Demo here

    【讨论】:

    • 您的解决方案适合 POC。但它不适用于我的实际查询。我会尽快回复确切的问题。
    • 这是正确的解决方案。但是有一个问题,我使用的是order by。这会改变行号。演示在这里 - sqlfiddle.com/#!6/5a30f/2
    • @unknown 我不确定我是否了解您的实际要求。如果您的行按seq 而不是id 排序,则在窗口函数的OVER 子句中使用此字段而不是id
    • 我只想对结果应用“order by”。不要与名称 seq 混淆。让我们假设有一个我试图订购的名称字段。同样的事情也会发生。
    • @unknown 这是不可能的。这就像想同时以两种不同的方式对单个字段进行排序。
    猜你喜欢
    • 1970-01-01
    • 2016-03-31
    • 2019-06-14
    • 2021-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-27
    • 1970-01-01
    相关资源
    最近更新 更多