我希望筛选表,以排除“金额”列的总和给予零的行以及按ID分组的行,例如,如果同一ID为“-10,10 and 15”。我希望排除-10 and 10的行,保留第15行
到目前为止,我能够使用GROUP BY
过滤表,但我需要获得ID才能在同一个表上再次执行选择,而且我还需要SUM
拆分。
CREATE Table #myData
(
Id INT,
DateInit date,
DebtorName varchar(10),
Trancode varchar(10),
Amount VARCHAR(50),
DebtorID varchar(50),
ClientRef NVARCHAR(256)
)
INSERT INTO #myData
VALUES
(1, '1/1/2022', 'BURNETTE', '13 P', '-53.42', '23916762', 'T081819513107-00009')
,(2, '1/1/2022', 'BURNETTE', '13 P', '-28.83', '23916761', 'T081819513107-00008')
,(3, '1/1/2022', 'BURNETTE', '13 P', '-12.08', '23916764', 'T081819513107-00010')
,(4, '1/1/2022', 'BURNETTE', '1 P', '12.08', '23916764', 'T081819513107-00010')
,(5, '1/1/2022', 'BURNETTE', '1 P', '28.83', '23916761', 'T081819513107-00008')
,(6, '1/1/2022', 'BURNETTE', '1 P', '53.42', '23916762', 'T081819513107-00009')
,(7, '1/1/2022', 'BURNETTE', '2 P', '66.41', '23916762', 'T081819513107-00009')
,(8, '1/1/2022', 'BURNETTE', '2 P', '71.10', '23916762', 'T081819513107-00009')
,(9, '1/1/2022', 'BURNETTE', '2 P', '12.08', '23916764', 'T081819513107-00010')
SELECT
DebtorID,
SUM(CASE
WHEN TRY_PARSE(A.Amount AS float) IS NULL
THEN (-1) * CAST(SUBSTRING(A.Amount, CHARINDEX('-', A.amount) + 1, LEN(A.Amount)) AS float)
ELSE CAST(A.Amount AS float)
END) AS amountSum
FROM
#myData A
GROUP BY
DebtorID
HAVING
SUM(CASE
WHEN TRY_PARSE(A.Amount AS float) IS NULL
THEN (-1) * CAST(SUBSTRING(A.Amount, CHARINDEX('-', A.Amount) + 1, LEN(A.Amount)) AS float)
ELSE CAST(A.Amount AS float)
END) != 0
但此查询返回:
| 借方ID|金额|
| - ------|- ------|
| 小行星239|一百三十七点五一|
| 小行星239|十二时零八分|
最终目标是过滤这些结果并将它们保存在与原始表相同的另一个表中(#myData
)。
这就是我想要输入#myData的结果:
| 身份证|初始化日期|债务人姓名|代码转换|数量|借方ID|客户参考|
| - ------|- ------|- ------|- ------|- ------|- ------|- ------|
| 六个|2022年1月1日|伯内特|2名专业人员|六十六点四一分|小行星239|编号:T081819513107-00009|
| 八个|2022年1月1日|伯内特|2个p|七十一点一零|小行星239|编号:T081819513107-00009|
| 八个|2022年1月1日|伯内特|2个p|十二时零八分|小行星239|编号:T081819513107-00010|
我将感激任何帮助,谢谢!
更新2 -新场景
谢谢你的帮助,但是这个场景必须有相同的输出。
| 身份证|初始化日期|债务人姓名|代码转换|数量|借方ID|客户参考|
| - ------|- ------|- ------|- ------|- ------|- ------|- ------|
| 1个|2022年1月1日|伯内特|13名专业人员| -53.42 |小行星239|编号:T081819513107-00009|
| 第二章|2022年1月1日|伯内特|13名专业人员| -12.08 |小行星239|编号:T081819513107-00010|
| 三个|2022年1月1日|伯内特|1个p|十二时零八分|小行星239|编号:T081819513107-00010|
| 四个|2022年1月1日|伯内特|1个p|二十八点八三分|小行星239|编号:T081819513107-00008|
| 五个|2022年1月1日|伯内特|1个p|六十六点四一分|小行星239|编号:T081819513107-00009|
| 六个|2022年1月1日|伯内特|13个| -28.83 |小行星239|编号:T081819513107-00008|
| 七|2022年1月1日|伯内特|1个p|五十三点四二|小行星239|编号:T081819513107-00009|
| 八个|2022年1月1日|伯内特|1个p|七十一点一零|小行星239|编号:T081819513107-00009|
| 九|2022年1月1日|伯内特|2个p|十二时零八分|小行星239|编号:T081819513107-00010|
预期结果输出:
| 身份证|初始化日期|债务人姓名|代码转换|数量|借方ID|客户参考|
| - ------|- ------|- ------|- ------|- ------|- ------|- ------|
| 五个|2022年1月1日|伯内特|1个p|六十六点四一分|小行星239|编号:T081819513107-00009|
| 八个|2022年1月1日|伯内特|1个p|七十一点一零|小行星239|编号:T081819513107-00009|
| 九|2022年1月1日|伯内特|2个p|十二时零八分|小行星239|编号:T081819513107-00010|
1条答案
按热度按时间b4wnujal1#
如果您需要原始数据集,但又想包含一个聚合,或者想根据聚合进行过滤或排序,那么 Window Functions 可以帮您大忙。
**更新:**问题的性质略有变化,但原始建议仍然相同,我们不想使用
GROUP BY
,因为我们丢失了详细信息行,如果必须在sing表达式中执行此操作,则 * 窗口函数 * 提供了简单的语法解决方案在这个解决方案中,我使用CTE来区分金额列的格式和聚合的计算,但是您可以使用
CROSS APPLY
来进行格式设置。注意,在这个解决方案中,我们根本没有应用
SUM
,我们只是匹配值,这意味着对于非数字值的工作是相同的解决方案在小提琴上,我试着详细描述了一些步骤,但最终,我们按以下顺序处理数据:
1.将
Amount
列格式化为数值1.使用
ROW_NUMBER()
window function标识唯一的Amount
和DebtorID
值对1.过滤出匹配的唯一对
1.返回已处理的数据,这些数据与您可能需要的任何其他列或引用联接在一起。
看看这把小提琴:https://dbfiddle.uk/XY8h2uvG
因为我们没有专门对
Amount
列应用聚合,所以它不需要是数字,我们实际上可以使用简单的字符串比较,您必须在您的环境中分析它,但下面的查询是类似的:根据数据源的复杂性和可能可用(或NOT可用)的索引,在对临时表的多个查询中处理这个问题可能更有意义。
以下是以前的尝试,以解决原来的要求。我选择离开这些在由于模糊的OP标题,虽然过程和解决方案(包括小提琴)可能会证明有助于其他人谁发现自己在这一页。
https://dbfiddle.uk/l-64hpZF
| 识别号|借方ID|金额|合计金额|客户参考|
| - ------|- ------|- ------|- ------|- ------|
| 1个|小行星239| -53.42 |一百三十七点五一|编号:T081819513107-00009|
| 三个|小行星239| -12.08 |十二时零八分|编号:T081819513107-00010|
| 四个|小行星239|十二时零八分|十二时零八分|编号:T081819513107-00010|
| 六个|小行星239|五十三点四二|一百三十七点五一|编号:T081819513107-00009|
| 七|小行星239|六十六点四一分|一百三十七点五一|编号:T081819513107-00009|
| 八个|小行星239|七十一点一|一百三十七点五一|编号:T081819513107-00009|
| 九|小行星239|十二时零八分|十二时零八分|编号:T081819513107-00010|
如果
HAVING
子句要删除***LOT***的记录,您还可以将GROUP BY
的结果联接回原始集合,那么这可能比 *Window函数 * 更有效更新:运行余额-仅显示自零余额以来的最近交易
如果我们需要平衡交易,那么一个简单的解决方案是,我们可以用相同的
DebtorID
来计算前面所有行的运行余额。https://dbfiddle.uk/DVRoMoNd更新#2:按〉0过滤是不够的
我发现,即使前面的fiddle返回了正确的答案,但如果事务历史记录先前为负数,然后又回到零,那么它就不起作用了。下面的查询查找运行余额 * 小于或等于 * 零的最后一次时间,并返回该时间之后的所有事务:https://dbfiddle.uk/exwm9OwA
| 识别号|借方ID|金额|客户参考|
| - ------|- ------|- ------|- ------|
| 七|小行星239|六十六点四一分|编号:T081819513107-00009|
| 八个|小行星239|七十一点一|编号:T081819513107-00009|
| 九|小行星239|十二时零八分|编号:T081819513107-00010|
数据的 * 序列 * 对于
SumAmount
列很重要,在本例中,我无法使用时间戳,因为值的粒度不够,ID
是此数据集 * 的自然选择。在您的生产代码中,可能有更合适的基于时间的候选项。SumAmount
是关于 * 输入时间 * 的简单 * 动态余额 *。