Pau*_*dew 5 sql select group-by subquery having
我有一张交易表.每个交易都有交易ID,会计期间(AP),过帐价值(PV)以及其他字段.一些ID是重复的,通常是因为事务是错误完成的.举个例子,表的一部分可能如下所示:
ID PV AP
123 100 2
123 -100 5
Run Code Online (Sandbox Code Playgroud)
在这种情况下,交易在AP2中添加,然后在AP5中删除.
另一个例子是:
ID PV AP
456 100 2
456 -100 5
456 100 8
Run Code Online (Sandbox Code Playgroud)
在第一个例子中,问题在于,如果我正在分析在AP2中花费的内容,那么在那里存在一个实际上不应该被考虑的事务,因为它在AP5中被再次取出.在第二个示例中,不应考虑后两个事务,因为它们相互抵消.
我想标记尽可能多的交易,不应该将其视为错误的.为了识别这些交易,我想找到具有重复ID的那些,其PV总和为零(如上面的ID 123)或最早的PV等于总和(PV)的交易,如第二个例子中所示.这第二个条件是导致我悲痛的原因.
到目前为止我有
SELECT *
FROM table
WHERE table.ID IN (SELECT table.ID
FROM table
GROUP BY table.ID
HAVING COUNT(*) > 1
AND (SUM(table.PV) = 0
OR SUM(table.PV) = <PV of first transaction in each group>))
ORDER BY table.ID;
Run Code Online (Sandbox Code Playgroud)
V形臂章是我正在尝试做的事情,而且我被卡住了.我可以这样做,还是我可以在SQL中使用其他方法来执行此操作?
编辑1:顺便说一句,我忘了说我正在使用SQL Compact 3.5,以防万一.
编辑2:我认为上面的代码片段有点误导.我仍然想要标记具有重复ID的事务,其中sum(PV)= 0,如第一个示例中所示.但是,在最早交易的PV = sum(PV)的情况下,如第二个例子中那样,我实际想要的是保持最早的交易并用相同的ID标记所有其他交易.对不起,如果这引起混乱.
编辑3:我一直在玩Clodoaldo的解决方案并取得了一些进展,但仍然无法得到我想要的东西.我试图让我知道的交易肯定是错误的.假设表中还包含以下事务:
ID PV AP
789 100 2
789 200 5
789 -100 8
Run Code Online (Sandbox Code Playgroud)
在这个例子中,sum(PV)<> 0和最早的PV <> sum(PV)所以我不想将这些中的任何一个标记出来.
如果我修改Clodoaldo的查询如下:
select t.*
from
t
left join (
select id, min(ap) as ap, sum(pv) as sum_pv
from t
group by id
having sum(pv) <> 0
) s on t.id = s.id and t.ap = s.ap and t.pv = s.sum_pv
where s.id is null
Run Code Online (Sandbox Code Playgroud)
这给出了结果
ID PV AP
123 100 2
123 -100 5
456 -100 5
456 100 8
789 100 3
789 200 5
789 -100 8
Run Code Online (Sandbox Code Playgroud)
虽然前4个交易都没问题(它们会被标记出来),但789交易也在那里,我不想要它们.但我无法弄清楚如何修改查询,以便它们不被包括在内.有任何想法吗?
尝试这样的事情:
UPDATE
Transactions
SET
IsError = true
WHERE
EXISTS
(SELECT
NULL
FROM
Transactions SubsequentTransactions
WHERE
Transactions.ID = SubsequentTransactions.ID
AND Transactions.AP < SubsequentTransactions.AP
AND Transactions.PV = -1 * SubsequentTransactions.PV)
Run Code Online (Sandbox Code Playgroud)
我认为这会起作用。我根本没有测试过它,所以我建议您首先在 select 语句中使用 WHERE 子句,以确保它只会影响您想要的行。
这不会将负交易标记为错误(您可能需要也可能不需要),但第二个示例除外。在您的第二个示例中,有第三条记录,如果单独获取第二条记录,则会取消第二条记录。您可能会发现需要扩展逻辑才能完全获得所需的内容,但这应该可以帮助您入门。