我有一张桌子:
create table transaction_log (
id serial,
operation_type character varying(36),
date timestamp with time zone,
sum double precision,
user_id integer,
PRIMARY KEY(id)
);
它保留两种类型的操作:block
和unblock
用于operation
的多个用户(contragent_id)和批次(lot_id)和日期时间字段。
例如:
id, sum, operation_type, date, user_id
1, 5900, blocked, 2018-01-05 11:00, 1
2, 3500, blocked, 2018-01-08 12:00, 2
3, 5900, unblock, 2018-02-11 09:00, 1
4, 1000, blocked, 2018-01-09 05:00, 3
5, 3500, unblock, 2018-01-24 19:00, 2
因此,我需要获取SQL来获取所有具有相应取消阻止操作日期(如果存在)的阻止操作。例如:block_ID,总和,blocked_date,unblock_date。因此,我需要从示例数据中获取: 例如:
block_ID, sum, blocked_date, unblock_date
1, 5900, 2018-01-05 11:00, 2018-02-11 09:00
2, 3500, 2018-01-08 12:00, 2018-01-24 19:00
4, 1000, blocked, 2018-01-09 05:00, null
我想为此需要一个WITH语句,但是我无法理解如何正确匹配记录。
任何帮助表示赞赏。
BTW Postgres 9.4
答案 0 :(得分:0)
您可以尝试以下方式
with block as
(
select * from transactions
where operation='blocked'
),
unblock as
(
select * from transactions
where operation='unblock'
)
select block.id as block_ID, block.sum,
block.date, unblock.date from block
left join unblock on block.user_id=unblock.user_id
答案 1 :(得分:0)
如果您的数据是一致的,则您仅在查找冻结日期之后的最小解除冻结日期。您可以在select user_id, sum, date as block,
(
select min(ub.date)
from blocktable ub
where ub.operation_type = 'unblock'
and ub.user_id = b.user_id
and ub.date >= b.date
) as unblock
from blocktable b
where operation_type = 'blocked';
子句的子查询中获得它:
FROM
或在select b.user_id, b.sum, b.date as block, ub.unblock
from blocktable b
left join lateral
(
select min(ub.date) as unblock
from blocktable ub
where ub.operation_type = 'unblock'
and ub.user_id = b.user_id
and ub.date >= b.date
) b
where operation_type = 'blocked';
子句中使用横向联接:
select *
from blocktable b
left join lateral
(
select *
from blocktable ub
where ub.operation_type = 'unblock'
and ub.user_id = b.user_id
and ub.date >= b.date
order by ub.date
fetch first 1 row only
) as unblock
where operation_type = 'blocked';
通过横向连接甚至可以得到整行:
LEAD
获取单个日期的另一个选项是select user_id, sum, block, unblock
from
(
select
user_id,
sum,
date as block,
lead(date) over (partition by user_id order by date, operation_type) as unblock,
operation_type
from mytable
) block_and_unblock
where operation_type = 'blocked';
:
public static void main(String args[]) throws Exception {
String data="Test123";
String key="AABBCC11";
String cipher=new String(OpenSSL.encrypt("AES256", key.toCharArray(), data.getBytes(), true));
//cipher=enc(data,key);
String clear=new String(OpenSSL.decrypt("AES256", key.toCharArray(), cipher.getBytes()));
System.out.println(clear);
}
public static String enc(String text, String key) throws Exception {
Key keySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
Cipher c = Cipher.getInstance("AES");
c.init(Cipher.ENCRYPT_MODE, keySpec);
byte[] encValue = c.doFinal(text.getBytes());
return java.util.Base64.getEncoder().encodeToString(encValue);
}
如果您希望查询即使在出现不一致的情况下也能正常工作(尤其是两个彼此阻塞的记录或两个彼此不受阻塞的记录),则可能必须顺序选择数据,即在递归查询中或在应用程序中。