Sql 如何使同一项目的多次出现与第一次出现的值不同?

Sql 如何使同一项目的多次出现与第一次出现的值不同?,sql,sql-server-2008,tsql,Sql,Sql Server 2008,Tsql,我有一个如下所示的数据库: label_id, scan_type, scan_cost 001, A40, 70 001, A40, 70 002, A40, 85 003, A40, 85 003, A40, 85 001, A40, 70 001, A40, 0 002, A40, 85 003, A40, 85 003, A40, 0 有些行看起来像这样: label_id, scan_type, scan_cost 001, A40, 70 001, A40, 70 002,

我有一个如下所示的数据库:

label_id, scan_type, scan_cost
001, A40, 70
001, A40, 70
002, A40, 85
003, A40, 85
003, A40, 85
001, A40, 70
001, A40, 0
002, A40, 85
003, A40, 85
003, A40, 0
有些行看起来像这样:

label_id, scan_type, scan_cost
001, A40, 70
001, A40, 70
002, A40, 85
003, A40, 85
003, A40, 85
001, A40, 70
001, A40, 0
002, A40, 85
003, A40, 85
003, A40, 0
我需要生成一个如下所示的结果集:

label_id, scan_type, scan_cost
001, A40, 70
001, A40, 70
002, A40, 85
003, A40, 85
003, A40, 85
001, A40, 70
001, A40, 0
002, A40, 85
003, A40, 85
003, A40, 0
也就是说,如果同一个
标签id
多次出现,则需要将
扫描成本
列设置为0,但每个
标签id
的第一次出现的值需要保持不变

如果标签id改变了什么,那么标签id就不是连续的


有可能在SQL中实现这种行为吗?注意SQL方言是T-SQL,Microsoft SQL Server 2008

此查询返回您要查找的内容:

SELECT
    label_id
,   scan_type
,   CASE WHEN row_number() OVER (PARTITION BY label_id ORDER BY scan_type)=1
        THEN scan_cost
        ELSE 0
    END
FROM test
ORDER BY label_id, scan_type
此解决方案背后的思想是按
label\u id
对数据进行分区,并使用它来决定保留哪些数据

我使用了
orderby
子条款中的
scan\u type
,这并不理想。如果您的实际表中有一列包含更适合确定第一行的数据,例如时间戳列,则应改用另一列。外部
order by
中的第二列需要与内部
order by
中的第二列相同


这是上此查询的链接。

您真的需要返回重复的行吗?也就是说,不只是将这些行的
scan\u成本
归零,而只是不包括后续的行?此外,在您的输入示例中,对于任何给定的
标签id
,每行的
scan\u成本
总是相同的。整个数据集都是这样吗?不,可能会改变。是的,我确实需要包含重复的行。实际情况是,每次扫描都有成本,但每个标签id只向用户收取一次费用。因此,通过将除第一行之外的所有其他行的扫描成本设置为0,我可以对扫描成本列求和()并向用户提供正确的收费金额。您丢失了一个订单,或者结果可以出来wrong@RichardTheKiwi我在末尾添加了
orderby
,并提到了一些关于内部
orderby
的注意事项。谢谢我想你没抓住重点。SQL Server可以以一种方式返回最终结果集,并以完全不同的方式返回最终结果集。因为您的分区是“label\u id”,而ORDER BY是单列,如果扫描成本不在第一行,那么结果看起来就不正确,这就是问题的全部目的。@RichardTheKiwi数据缺少一个在分区内进行排序的好列,这就是为什么我在第一次编辑中添加了一段话,说
scan\u type
不是一个好的选择,时间戳会更好。我认为在这种不打成一片的情况下,实际上需要在外部查询中保留行号和
按标签的顺序\u id,rownum
,才能准确。是的,我的意思是需要两个级别