Oracle sql表名为" TEST"
id amount date
1 0 1/2/2015
2 100 1/2/2015
3 2 5/10/2016
4 55 5/10/2016
我想选择有两行具有相同日期的行,其中一个量为0而另一个量大于0,而金额较低的行也具有最低的ID。
这是我到目前为止所做的,但我不确定如何确保0金额的行也具有两行的较低ID。
select * from TEST
where id in(
select id
(select id,
created_dt,
sum(case when amount=0 then 1 else case when amount>0 then 2 end end)
over (partition by d.created_dt) as checkAmount
from TEST)
where checkAmount = 3)
答案 0 :(得分:0)
我将您的意图解释为只保留那些有两行符合您已经尝试的查询的日期组。如果您的问题是关于符合条件的行对,那么这种方法就不是您需要的方法。
根据您的金额范围,您可以使用缩放系数将ID和金额合并为一个值:
Title Cell
File Info Cell
Time Date Cell
Data1, Data 2
Data1, Data 2
Data1, Data 2
Data1, Data 2
Data1, Data 2
Data1, Data 2
Data1, Data 2
Data1, Data 2
Data1, Data 2
Data1, Data 2
Data1, Data 2
Data1, Data 2
Data1, Data 2
Data1, Data 2
....(continues for around 800 rows)
Second Table Title Cell
Col1Title, Col2Title, ColTitle, Col4Title ....(continues for around 50 columns)
Data 3, Data4, Data 5, Data6 ....(continues for around 50 columns)
Data 3, Data4, Data 5, Data6 ....(continues for around 50 columns)
Data 3, Data4, Data 5, Data6 ....(continues for around 50 columns)
Data 3, Data4, Data 5, Data6 ....(continues for around 50 columns)
Data 3, Data4, Data 5, Data6 ....(continues for around 50 columns)
Data 3, Data4, Data 5, Data6 ....(continues for around 50 columns)
Data 3, Data4, Data 5, Data6 ....(continues for around 50 columns)
Data 3, Data4, Data 5, Data6 ....(continues for around 50 columns)
...(Continues for around 1500 rows)
End of CSV
同样,你可以尝试这个(作为最终条件的替代品)虽然它可能会导致溢出而不需要小心。这个想法应该仍然合理:
select created_dt, min(id), max(id), max(amount)
from TEST
group by created_dt
having
count(*) = 2 and min(amount) = 0 and max(amount) > 0
and min(10000 * id + amount) = min(10000 * id)
另一种可能聪明的方式:
and max(id) * max(amount) = max(id * amount)
或者最安全和最简单的,这两个选项中的任何一个:
and min(id) = max(case when amount = 0 then id else -id end)
完整的查询是:
and min(id) + min(amount) = min(id + amount)
and max(id) + max(amount) = max(id + amount)
编辑:将所有数据放在一行可能确实是一个优势,但我意识到您可能希望将其保留在两行中。如果您只是返回这些值而不是其他列,那么它仍然很容易获得。 请注意,如果有必要,您仍然可以使用ID来连接它们。
select created_dt, min(id), max(id), max(amount)
from TEST
group by created_dt
having
count(*) = 2 and min(amount) = 0 and max(amount) > 0
and min(id) + min(amount) = min(id + amount)
此查询可以在没有with data as (
select
created_dt,
min(id) as min_id, max(id) as max_id, max(amount) as max_amount
from TEST
group by created_dt
having
count(*) = 2 and min(amount) = 0 and max(amount) > 0
and min(id) + min(amount) = min(id + amount)
)
select split.*
from data cross apply (
values
(created_dt, min_id, 0),
(created_dt, max_id, max_amount)
) split(created_dt, id, amount)
,with
和cross apply
的情况下编写,前提是这些查询不是您可以使用的任何工具。
答案 1 :(得分:0)
Oracle安装程序:
CREATE TABLE test ( id, amount, dt ) AS
SELECT 1, 0, DATE '2016-02-01' FROM DUAL UNION ALL -- Valid
SELECT 2, 100, DATE '2016-02-01' FROM DUAL UNION ALL -- Valid
SELECT 3, 2, DATE '2016-10-05' FROM DUAL UNION ALL -- Non-zero group
SELECT 4, 55, DATE '2016-10-05' FROM DUAL UNION ALL -- Non-zero group
SELECT 5, 5, DATE '2016-01-01' FROM DUAL UNION ALL -- +ve before zero
SELECT 6, 0, DATE '2016-01-01' FROM DUAL UNION ALL -- +ve before zero
SELECT 7, -5, DATE '2016-01-01' FROM DUAL UNION ALL -- -ve
SELECT 8, 0, DATE '2016-01-02' FROM DUAL UNION ALL -- More than 2 rows
SELECT 9, 1, DATE '2016-01-02' FROM DUAL UNION ALL -- More than 2 rows
SELECT 10, 2, DATE '2016-01-02' FROM DUAL UNION ALL -- More than 2 rows
SELECT 11, 0, DATE '2016-01-03' FROM DUAL UNION ALL -- Valid
SELECT 12, -1, DATE '2016-01-03' FROM DUAL UNION ALL -- -ve
SELECT 13, 2, DATE '2016-01-03' FROM DUAL; -- Valid
<强>查询强>:
SELECT id,amount,dt
FROM (
SELECT t.*,
CASE
WHEN amount = 0 THEN LEAD( CASE WHEN amount > 0 THEN id END ) IGNORE NULLS OVER ( PARTITION BY dt ORDER BY id )
WHEN amount > 0 THEN LAG( CASE WHEN amount = 0 THEN id END ) IGNORE NULLS OVER ( PARTITION BY dt ORDER BY id )
END AS is_valid,
COUNT( CASE amount WHEN 0 THEN 1 END ) OVER ( PARTITION BY dt ) AS num_zeros,
COUNT( CASE WHEN amount > 0 THEN 1 END ) OVER ( PARTITION BY dt ) AS num_positive
FROM test t
)
WHERE is_valid IS NOT NULL
AND num_zeros = 1
AND num_positive = 1;
<强>输出强>:
ID AMOUNT DT
---------- ---------- -------------------
11 0 2016-01-03 00:00:00
13 2 2016-01-03 00:00:00
1 0 2016-02-01 00:00:00
2 100 2016-02-01 00:00:00
答案 2 :(得分:0)
我会将此作为一个简单的UNION ALL查询:获取金额= 0的记录,其中存在较高的ID,在同一日期具有正数量加上获得的数量&gt; 0记录,其中存在较低的ID且数量为零在同一天。
select *
from test
where amount = 0
and exists
(
select *
from test other
where other.created_dt = test.created_dt
and other.id > test.id
and amount > 0
)
union all
select *
from test
where amount > 0
and exists
(
select *
from test other
where other.created_dt = test.created_dt
and other.id < test.id
and amount = 0
);