【问题标题】:Same index/ID based on another column value基于另一列值的相同索引/ID
【发布时间】:2015-11-12 03:06:06
【问题描述】:

这是我在这个网站上的第一个问题,我想知道,如果我在 SQL 中有这样的表

  • 价值
  • 一个
  • 一个
  • 一个
  • 一个
  • 一个
  • b
  • b
  • b
  • c
  • c
  • 一个
  • 一个
  • b
  • b

如何在查询中生成序列号或 ID 列表,使其根据值列发生变化,这就是我想要的:

  • 价值;身份证
  • 一个; 1
  • 一个; 1
  • 一个; 1
  • 一个; 1
  • 一个; 1
  • b; 2
  • b; 2
  • b; 2
  • c ; 3
  • c ; 3
  • 一个; 4
  • 一个; 4
  • b; 5
  • b; 5

提前感谢大家的回答。

【问题讨论】:

  • 您使用的是 SQL Server 还是 MS Access?
  • 感谢您的光临,我将使用 SQL 服务器
  • SQL 表表示无序集。除非您有指定排序的 id 或创建日期,否则没有排序。因此,您的要求是不可能的。

标签: sql sql-server ms-access


【解决方案1】:

您可以通过一系列查询来做到这一点。 1. 从包含自动增量字段和文本字段的表格开始,仅此而已。不放任何记录。 2. 针对您的表编写一个聚合查询,按您的值字段分组。 3. 编写一个追加查询,将第 2 步中的查询中的记录追加到第 1 步中的表中。该查询的结果将是您想要的。

【讨论】:

  • 感谢大家的回答,对于我所测试的内容,我使用了密集的 Rank 函数,但它没有帮助,因为它对值进行分组并对它们进行排序,我希望记录保持原样。如果我使用这种方法为每个值添加另一个值为 1 到 14 的列,有没有办法实现我想要的?这样做的要点是我不希望对 ABC... 值进行排序,我希望它们像 Excel 列一样保留。
  • 更新了我的答案,添加了带有光标的选项。我不知道如何只用一个查询来解决这个问题(不使用循环)
  • 我的解决方案不需要任何程序代码,只需要一个表和 2 个查询。
【解决方案2】:
CREATE TABLE mytable(Id int, Value char(1))
INSERT INTO mytable
SELECT 1,'a'
UNION ALL
SELECT 2,'a'
UNION ALL
SELECT 3,'a'
UNION ALL
SELECT 4,'a'
UNION ALL
SELECT 5,'a'
UNION ALL
SELECT 6,'b'
UNION ALL
SELECT 7,'b'
UNION ALL
SELECT 8,'b'
UNION ALL
SELECT 9,'a'
UNION ALL
SELECT 10,'a'
UNION ALL
SELECT 11,'b'
UNION ALL
SELECT 12,'b'
UNION ALL
SELECT 13,'c'
UNION ALL
SELECT 14,'c';

WITH cte AS 
(SELECT 
    t1.Id
    ,t1.Value
    ,ROW_NUMBER() OVER (ORDER BY t1.Id) RowNo
FROM mytable t1
LEFT OUTER JOIN mytable t2 ON t1.Id = t2.Id - 1
WHERE 
    t2.id IS NULL
    OR t1.Value <> t2.Value)
SELECT 
mytable.Id
,mytable.Value
,MIN(cte.RowNo) RowNo
FROM
mytable
LEFT OUTER JOIN cte ON mytable.Value = cte.Value AND mytable.Id <= cte.Id
GROUP BY 
    mytable.Id
,mytable.Value
ORDER BY
mytable.id

【讨论】:

    【解决方案3】:

    Gordon Linoff 关于不订购是正确的,因此不可能完全按照您的要求进行 但是如果你有一个额外的列要在 SQL Server 中排序,你可以使用 DENSE_RANK 来分配数字:

    --create table Test(col varchar(100))
    --insert into Test values('a'),('a'),('a'),('b'),('b'),('c'),('d')
    
    select col, DENSE_RANK() over (Order BY col)
    from Test
    

    它会产生

    a 1
    a 1
    a 1
    b 2
    b 2
    c 3
    d 4
    

    或者,总是有一个循环或光标循环选项。此脚本似乎正在产生您的预期结果:

    /*
        drop table Test
        create table Test(ExcelRowId int not null identity primary key, data varchar(100) not null, idx int)
        insert into Test(data) values('a'),('a'),('a'),('a'),('a'),('b'),('b'),('b'),('c'),('c'),('a'),('a'),('b'),('b')
    */
    
    declare @idx int, @prev_data varchar(100), @data varchar(100)
    set @idx = 0
    declare cur cursor for select Data from Test order by ExcelRowId for update of idx
    open cur
    fetch next from cur into @data
    while @@FETCH_STATUS = 0
    begin
        if @prev_data is null or @data <> @prev_data set @idx = @idx + 1
        set @prev_data = @data
    
        update Test set Idx = @Idx WHERE CURRENT OF cur
    
        fetch next from cur into @data
    end
    close cur
    deallocate cur
    
    select * from test
    

    【讨论】:

      猜你喜欢
      • 2015-05-24
      • 2018-07-14
      • 2020-12-12
      • 1970-01-01
      • 2021-11-27
      • 2019-09-24
      • 2020-10-11
      • 2021-12-08
      • 2021-01-12
      相关资源
      最近更新 更多