【问题标题】:SQL Server : identify first row value appears in column and insert into tableSQL Server:识别列中出现的第一行值并插入表中
【发布时间】:2017-08-07 21:30:33
【问题描述】:

我的表结构如下:

Id     | TransNbr | Type |
-------+----------+------+
1235   | 220      | A    |
1236   | 221      | A    |
1237   | 220      | A    |
1238   | 220      | B    |
1239   | 221      | B    |

我需要在此表中添加一个新列,以指示这是否是 A 类型的第一个 TransNbr

我能够使以下SELECT 查询工作...但我不确定现在如何将新填充FirstTime 列添加到INVOICE 表:

SELECT 
    *, 
    CASE 
       WHEN (ROW_NUMBER() OVER(PARTITION BY TransNbr ORDER BY Id)) = 1 
          THEN 1 
          ELSE 0 
    END FirstTime
FROM INVOICE
WHERE Type = 'A'

【问题讨论】:

  • 您的代码似乎与“指示这是否是 A 型的第一个 TransNbr”无关。您希望它识别哪些行?

标签: sql sql-server row-number


【解决方案1】:

如果您想更新 id 为 1235 的行上的字段,那么您可以这样做:

with toupdate as (
      select i.*, row_number() over (partition by type order by id) as seqnum
      from invoice
      where type = 'A'
     )
update toupdate
    set FirstTime = 1;

如果这不能满足您的需求,您可以调整 CTE 中的逻辑。

如果你没有FirstTime 标志,你可以这样做:

alter table invoice add FirstTime tinyint default 0;

【讨论】:

  • 您的逻辑与 OP 提供的 SELECT 不同。所有类型为 A 的行都将得到 1,其中包括具有相同 transnbr 的两行。此外,OP 在 transnbr 上完成了分区,而您在 type 字段上完成了分区。
  • @Eli 。 . .很难说出 OP 真正想要什么。我按照描述进行:“我需要在此表中添加一个新字段,以指示这是否是 A 类的第一个 TransNbr。” OP 会选择两个不同的 TransNbrs,这绝对不是本意。
【解决方案2】:

首先您需要创建 firsttime 字段:

ALTER TABLE INVOICE
ADD firsttime BIT NULL;--or tinyint

这应该相应地更新新生成的列。

UPDATE invoice
SETfirsttime = a.firsttime
FROM invoice 
INNER JOIN  
(
SELECT  id, 
    CASE WHEN (ROW_NUMBER() OVER(PARTITION BY TransNbr ORDER BY 
    Id))=1 THEN 1 ELSE 0 END FirstTime
FROM INVOICE 
WHERE Type = 'A')a 
ON invoice.id = a.id

用您的样本数据进行了测试,看起来不错。

【讨论】:

  • 这很棒!感谢您帮助我解决这个问题!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-03
  • 1970-01-01
  • 2022-01-07
  • 2019-08-26
  • 2021-08-03
相关资源
最近更新 更多