【问题标题】:How to increment in a select query如何在选择查询中递增
【发布时间】:2011-03-13 23:23:02
【问题描述】:

我正在处理一个查询,我想增加其中一个字段并在键值不同时重新启动计数器。

我知道这段代码不起作用。以编程方式,这就是我想要的......

declare @counter int, @id
set @counter = 0
set @id = 0

select distinct 
  id, 
  counter = when id = @id 
              then @counter += 1
            else @id = id  
               @counter = 1     

...最终结果如下所示:

ID    Counter
3     1
3     2 
3     3
3     4
6     1
6     2
6     3
7     1

是的,我被 SQL2k 困住了。否则 row_number() 会起作用。

【问题讨论】:

  • 根据查询中可用的其余内容,Row_Number() 可能会有所帮助吗?
  • @reallyJim:如果他们使用 SQL2K,如标签所示,那么 ROW_NUMBER 将不可用。
  • @LukeH 完全错过了这一点!

标签: sql sql-server tsql sql-server-2000


【解决方案1】:

假设一张桌子:

CREATE TABLE [SomeTable] (
  [id] INTEGER,
  [order] INTEGER,
  PRIMARY KEY ([id], [order])
);

在 Microsoft SQL Server 2000 中实现这一点的一种方法是使用子查询来计算具有相同 id 和较低排序的行。

SELECT *, (SELECT COUNT(*) FROM [SomeTable] counter 
           WHERE t.id = counter.id AND t.order < counter.order) AS row_num
FROM [SomeTable] t

提示:现在是 2010 年。很快您的 SQL Server 就可以驱动了。

如果您使用 SQL Server 2005 或更高版本,您将获得出色的新功能,例如 ROW_NUMBER() OVER (PARTITION...)

【讨论】:

  • SQL 2000 仍然很有趣。 13 岁以上,SQL Server 7.0 大部分时间都闷闷不乐,整天玩电子游戏。
  • 我们实际上正在开发 SQL2k 的第一辆汽车。如果他保持鼻子干净并取得好成绩,那将是他的 16 岁生日礼物。 ;o)
  • 他们长得太快了! 嗅探
  • Pfft - 当我尝试使用 CTE 或分析函数时,SQL 2000 和 7.0 不断告诉我要离开他们的草坪......
  • 这个方法不是假设表中有'order'字段吗?并且这个领域将不得不被维护。 OP 从来没有提到在他的表中有这个字段。这就是为什么我的方法使用临时表中的标识列对行进行编号的原因。我错过了什么吗?感谢您帮助理解。
【解决方案2】:

是的,你想要 ROW_NUMBER()。

我会尝试:

SELECT id, ROW_NUMBER() OVER (PARTITION BY ID ORDER BY ID) AS Counter

【讨论】:

  • 不能 - SQL Server 直到 v2005 才支持分析/排名/加窗函数
【解决方案3】:

执行此操作的一种方法是将数据放入临时表中,其中标识列用作行号。然后将计数器列计数为具有相同 Id 和较低行号 + 1 的其他行。

CREATE TABLE #MyData(
Id INT
);

INSERT INTO #MyData VALUES(3);
INSERT INTO #MyData VALUES(3);
INSERT INTO #MyData VALUES(3);
INSERT INTO #MyData VALUES(3);
INSERT INTO #MyData VALUES(6);
INSERT INTO #MyData VALUES(6);
INSERT INTO #MyData VALUES(6);
INSERT INTO #MyData VALUES(7);

CREATE TABLE #MyTempTable(
RowNum INT IDENTITY(1,1),
Id INT,
Counter INT
);

INSERT INTO #MyTempTable
SELECT Id, 0
FROM #MyData
ORDER BY Id;

SELECT Id, (SELECT COUNT(*) + 1 FROM #MyTempTable WHERE Id = t1.Id AND RowNum < t1.RowNum) AS 'Counter'
FROM #MyTempTable t1;

根据您的示例,您应该得到以下输出:

Id  Counter
3   1
3   2
3   3
3   4
6   1
6   2
6   3
7   1

【讨论】:

    【解决方案4】:

    拥有 row_number() 意味着您必须处理的相关子查询要少得多。 @Bill Karwin 的解决方案有效(+1);这是另一个做同样事情的版本,但可能更容易理解。 (我使用日期时间来确定排序。)

    --  Test table
    CREATE TABLE Test
     ( Id      int       not null
      ,Loaded  datetime  not null
     )
    
    --  Load dummy data with made-up distinct datetimes
    INSERT Test values (3, 'Jan 1, 2010')
    INSERT Test values (3, 'Jan 2, 2010')
    INSERT Test values (3, 'Jan 5, 2010')
    INSERT Test values (3, 'Jan 7, 2010')
    INSERT Test values (6, 'Feb 1, 2010')
    INSERT Test values (6, 'Feb 11, 2010')
    INSERT Test values (7, 'Mar 31, 2010')
    
    
    --  The query
    SELECT t1.Id, count(*) Counter
     from Test t1
      inner join Test t2
       on t2.Id = t1.Id
        and t2.Loaded <= t1.Loaded
     group by t1.Id, t1.Loaded
    
    
    --  Clean up when done
    DROP TABLE Test
    

    需要注意的是,如果没有良好的索引(甚至可能使用索引),这类查询的性能会很差,尤其是在大型表上。仔细检查优化!

    【讨论】:

      【解决方案5】:

      对于 MySql,我可以使用这个查询。

      SELECT (SELECT COUNT(id) +1 FROM sku s WHERE t.item_id = s.item AND s.id < t.sku_id) AS rowNumber, t.*
      FROM
      (select item.Name as itemName ,item.id as item_id , sku.Name as skuName ,sku.id as sku_id from item
          INNER JOIN sku ON item.id = sku.item
          WHERE item.active = 'Y' 
      ) t
      
      
      1   Roasted Pistachios (Salted, In Shell)   84  1 Pound Bags    84
      3   Roasted Pistachios (Salted, In Shell)   84  25 Pound Cases  1174
      5   Roasted Pistachios (Salted, In Shell)   84  12 x 2.6 Ounce Bags 5807
      2   Roasted Pistachios (Salted, In Shell)   84  5 Pound Bags    814
      4   Roasted Pistachios (Salted, In Shell)   84  Samples 4724
      6   Roasted Pistachios (Salted, In Shell)   84  12 x 3.2 Ounce Bags 18145
      4   Star Fruit  981 5 Pound Bags    17462
      1   Star Fruit  981 1 Pound Bags    2125
      3   Star Fruit  981 11 Pound Bags   2226
      2   Star Fruit  981 44 Pound Cases  2156
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-09-03
        • 1970-01-01
        • 2013-05-09
        • 1970-01-01
        • 1970-01-01
        • 2016-03-29
        相关资源
        最近更新 更多