【问题标题】:SQL Query on Aggregating the sequence numbers聚合序列号的 SQL 查询
【发布时间】:2017-10-02 20:00:36
【问题描述】:

我有一个表,其序列号从 1 到 90000 所以我想知道如何自动将值分配给序列号 比如说从 1 到 1000 我希望它们低于 1000 桶 从 1001 到 2000 低于 2000 桶 以此类推,最多可达 90000 条记录。

【问题讨论】:

  • 您指的是 SQL Server SEQUENCE 对象 - 还是只是行中连续的一系列数值?
  • 我将字段命名为序列,其中我的值为 1,2 ....90000,因此对于该值,我希望将数据分配到 1 到 1000 之类的组中应该低于 1000 1001 到 2000 应该在 2000 以下,以此类推,
  • 你的问题一点都不清楚。从别人的角度考虑这个问题。你想在这里做什么是没有任何意义的。

标签: sql-server tsql select


【解决方案1】:

您可以将该数字除以 1000,将其取底,然后再乘以 1000:

SELECT   1000*FLOOR(num/1000) + 1, COUNT(*)
FROM     mytable
GROUP BY FLOOR(num/1000)

【讨论】:

  • 我不认为这就是我要找的东西,我希望这样 Mureinik 从 1 到 1000 它们应该显示为 1000,从 1001 到 2000 它应该是 2000 等等,直到 90000,
  • @sweety 我编辑并修复了一个错误的错误。如果这不是您的意思,您能否编辑您的问题并添加实际结果以便更清楚?
  • select * from function(1,1000,1000) union all select * from fucntion(1001,2000,2000) 这里第一个值是起点,第二个值是终点,第三个value 是存储桶中的项目数。我要到90000
【解决方案2】:

Modulo (%) 运算符非常适合这样的事情...... 太简单了,感觉像是在作弊。

WITH 
    cte_n1 (n) AS (SELECT 1 FROM (VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) n (n)), 
    cte_n2 (n) AS (SELECT 1 FROM cte_n1 a CROSS JOIN cte_n1 b),
    cte_n3 (n) AS (SELECT 1 FROM cte_n2 a CROSS JOIN cte_n2 b),
    Sequense (n) AS (
        SELECT TOP 90000
            ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
        FROM
            cte_n3 a CROSS JOIN cte_n3 b
        )
SELECT 
    SequenseNumber = s.n, 
    GroupNumber = s.n - (s.n % 1000)
FROM
    Sequense s;

结果...

SequenseNumber       GroupNumber
-------------------- --------------------
1                    0
2                    0
3                    0
4                    0
5                    0
6                    0   
.........................   
997                  0
998                  0
999                  0
1000                 1000
1001                 1000
1002                 1000
1003                 1000
1004                 1000
1005                 1000
1006                 1000
1007                 1000
1008                 1000
1009                 1000
1010                 1000
.........................
89990                89000
89991                89000
89992                89000
89993                89000
89994                89000
89995                89000
89996                89000
89997                89000
89998                89000
89999                89000
90000                90000

(90000 rows affected)

【讨论】:

    【解决方案3】:

    下面的代码做你想做的事,它使用CEILING 和一个从 0 到 90K 工作的算法,如果你使用 num 必须是 DECIMAL int 小数点设置为 0。

    测试数据

    declare @tbl table(num decimal)
    insert into @tbl
    select 1 union
    select 999 union
    select 1000 union
    select 1001 union
    select 2001 union
    select 3001 union
    select 9999 union
    select 10000 union
    select 10001 union
    select 15001 union
    select 25001 union
    select 77006 union
    select 80000 union
    select 90000 
    

    查询

    SELECT distinct
    num,
    CASE WHEN num <= 10000 THEN 1000*CEILING(num/1000)
         WHEN num <= 20000 THEN 10000 + 1000*CEILING((num-10000)/1000)
         WHEN num <= 30000 THEN 20000 + 1000*CEILING((num-20000)/1000)
         WHEN num <= 40000 THEN 30000 + 1000*CEILING((num-30000)/1000)
         WHEN num <= 50000 THEN 40000 + 1000*CEILING((num-40000)/1000)
         WHEN num <= 60000 THEN 50000 + 1000*CEILING((num-50000)/1000)
         WHEN num <= 70000 THEN 60000 + 1000*CEILING((num-60000)/1000)
         WHEN num <= 80000 THEN 70000 + 1000*CEILING((num-70000)/1000)
         WHEN num <= 90000 THEN 80000 + 1000*CEILING((num-80000)/1000)
         ELSE 0
         END
    FROM     @tbl
    

    结果

    1       1000
    999     1000
    1000    1000
    1001    2000
    2001    3000
    3001    4000
    9999    10000
    10000   10000
    10001   11000
    15001   16000
    25001   26000
    77006   78000
    80000   80000
    90000   90000
    

    【讨论】:

    • @sweety,很高兴知道它有帮助,请将其标记为正确答案,以便我们帮助其他人。
    【解决方案4】:

    我将假设 Jason 发布的内容是 OP 正在寻找的内容。这是使用 getnumsAB 的一个细微变化,它正是为这种类型的事情而开发的。首先,我们将使用它来创建一些示例数据:

    样本数据

    if object_id('tempdb..#yourdata') is not null drop table #yourdata;
    select SequenceNumber = rn
    into #yourdata
    from dbo.GetNumsAB(1,90000,1,1);
    create unique clustered index uq_cl_yourdata on #yourdata(SequenceNumber);
    

    要了解我的解决方案,请先记下这个查询:

    select rn, n1, n2 from dbo.getnumsAB(0,90000,1000,1); 
    

    这会返回:

    rn    n1       n2
    ----- -------- --------
    1     0        1000
    2     1000     2000
    3     2000     3000
    4     3000     4000
    .... 
    87    86000    87000
    88    87000    88000
    89    88000    89000
    90    89000    90000
    

    解决方案

    select y.SequenceNumber, GroupNumber = n1
    from #yourdata y
    join dbo.getnumsAB(0,90000,1000,1) gn 
      on y.SequenceNumber >= n1 and y.SequenceNumber < n2;
    

    【讨论】:

      【解决方案5】:

      如果我没有遗漏什么,你不会只使用 case 语句吗?

      选择案例 当序列 = 1001 然后是“2000”

      等到9000?

      【讨论】:

      • 当序列 = 1001 时选择“1000”,然后选择“2000”
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-06-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-15
      • 2015-01-29
      • 2016-04-23
      相关资源
      最近更新 更多