SQL Server中实现发票金额仅匹配销售表对应首条记录其余置零
SQL Server中实现发票金额仅显示在同一SALESID的第一条销售记录中
需求说明
在SQL Server中关联销售表与发票表,将发票金额仅填充到同一SALESID对应的第一条销售记录中,其余记录的发票金额设为0,避免后续求和分析时出现重复计算。
示例表
销售表(Sales_table)
| ID | SALESID | ITEM | Details… |
|---|---|---|---|
| 1 | S1 | Item1 | |
| 2 | S1 | Item2 | |
| 3 | S1 | Item3 | |
| 4 | S2 | Item 4 | |
| 5 | S3 | Item 5 | |
| 6 | S3 | Item 6 |
发票表(Invoice_table)
| INVSALESID | Invoice amount |
|---|---|
| S1 | A |
| S2 | B |
| S3 | C |
| S4 | D |
| S5 | E |
| S6 | F |
当前问题
执行的SQL语句
Select s.*,Invoice_amount FROM Sales_table s join Invoice_table inv on s.salesid=inv.InvSalesId where s.ID = ( select top 1 s.ID FROM Sales_table s1 WHERE S.SALESID=S1.SALESID )
当前结果
| ID | SALESID | ITEM | Invoice amount |
|---|---|---|---|
| 1 | S1 | Item1 | A |
| 2 | S1 | Item2 | A |
| 3 | S1 | Item3 | A |
| 4 | S2 | Item 4 | B |
| 5 | S3 | Item 5 | C |
| 6 | S3 | Item 6 | C |
期望结果
| ID | SALESID | ITEM | Invoice amount |
|---|---|---|---|
| 1 | S1 | Item1 | A |
| 2 | S1 | Item2 | 0 |
| 3 | S1 | Item3 | 0 |
| 4 | S2 | Item 4 | B |
| 5 | S3 | Item 5 | C |
| 6 | S3 | Item 6 | 0 |
解决方案
使用ROW_NUMBER()窗口函数为每个SALESID分组内的记录编号,通过条件判断仅保留第一条记录的发票金额,其余设为0:
SELECT s.ID, s.SALESID, s.ITEM, s.[Details…], CASE WHEN ROW_NUMBER() OVER (PARTITION BY s.SALESID ORDER BY s.ID) = 1 THEN inv.[Invoice amount] ELSE '0' -- 若发票金额为数值类型,直接写0即可 END AS [Invoice amount] FROM Sales_table s LEFT JOIN Invoice_table inv ON s.SALESID = inv.INVSALESID
逻辑说明
PARTITION BY s.SALESID:按SALESID对销售记录分组ORDER BY s.ID:每个分组内按ID排序,确保第一条记录为该组中ID最小的条目CASE语句:判断当前记录是否为分组内第一条,是则显示对应发票金额,否则显示0LEFT JOIN:保留销售表中所有记录,即使无对应发票记录,此时发票金额会显示0
内容的提问来源于stack exchange,提问作者Ash
相关产品推荐
相关产品推荐

