我需要一个可以满足以下逻辑的查询。该逻辑是由我创建的,但我不是那种以SQL格式编写的专家。
逻辑是我们必须在客户端表中找到Y和L并复制列。 客户端中只有它的N,然后我们必须在“历史记录”中搜索第一个Y并更新,或者如果“历史记录”中没有Y,则必须寻找第一个L并更新
如果有人帮助我进行修改,我将不胜感激。
client
表包含最新数据,而client_h
表具有相同客户端的历史记录。
If client.FLAG = ‘Y’ or ‘L’ , Then
UPDATE client SET
client.FLAG_new = client.FLAG,
client.DT_new = client.DT
ELSE
If client.FLAG= ‘N’ then
select Min(client_h.DT) from client_h where client_h.FLAG=‘Y’
UPDATE client SET
client.FLAG_new = client_h.FLAG,
client.DT_new = client_h.D
Else
select Min(client_h.DT) from client_h where client_h.FLAG=‘L’
UPDATE client SET
client.FLAG_new = client_h.FLAG,
client.DT_new = client_h.DT
答案 0 :(得分:1)
以下查询在PostgreSQL中产生所需的结果。
表“客户”
| col_name | type | | -------- | --------- | | id | integer | | flag | text | | dt | timestamp | | flag_new | text | | dt_new | timestamp |
表“ client_h”
| col_name | type | | --------- | --------- | | client_id | integer | | flag | text | | dt | timestamp |
查询
with new_client(id,flag,dt) as ( select id, coalesce(ch.flag,c.flag), coalesce(ch.dt,c.dt) from client c left join lateral ( select flag,dt from client_h where client_id=c.id and flag!='N' order by flag='Y' desc, flag='L' desc, dt limit 1 ) ch on c.flag='N' ) update client set flag_new = nc.flag , dt_new = nc.dt from new_client nc where nc.id=client.id
答案 1 :(得分:1)
对于mysql-不在集合中使用case语句。
DROP TABLE IF EXISTS CLIENT,CLIENT_H;
CREATE TABLE CLIENT (ID INT, FLAG_new VARCHAR(1), FLAG VARCHAR(1), DT_new DATE, DT DATE);
CREATE TABLE CLIENT_H (ID INT, FLAG_new VARCHAR(1), FLAG VARCHAR(1), DT_new DATE, DT DATE);
TRUNCATE TABLE CLIENT;
INSERT INTO CLIENT VALUES
(1,NULL,'Y',NULL,'2018-01-01'),
(2,NULL,'L',NULL,'2018-01-01'),
(3,NULL,'N',NULL,'2018-01-01'),
(4,NULL,'K',NULL,'2018-01-01');
INSERT INTO CLIENT_H VALUES
(1,NULL,'Y',NULL,'2018-01-01'),
(2,NULL,'L',NULL,'2018-01-01'),
(3,NULL,'K',NULL,'2018-01-01'),
(3,NULL,'Y',NULL,'2018-02-01'),
(4,NULL,'M',NULL,'2018-01-01'),
(4,NULL,'L',NULL,'2018-03-01'),
(4,NULL,'K',NULL,'2018-04-01');
UPDATE CLIENT C
LEFT JOIN (SELECT * FROM CLIENT_H H WHERE DT = (SELECT MIN(DT) FROM CLIENT_H H1 WHERE H1.ID = H.ID AND H1.FLAG = 'Y')) HY ON HY.ID = C.ID
LEFT JOIN (SELECT * FROM CLIENT_H H WHERE DT = (SELECT MIN(DT) FROM CLIENT_H H1 WHERE H1.ID = H.ID AND H1.FLAG = 'L')) HN ON HN.ID = C.ID
SET
C.FLAG_NEW = CASE WHEN C.FLAG IN ('Y','L') THEN C.FLAG
WHEN C.FLAG = 'N' AND HY.FLAG = 'Y' THEN HY.FLAG
WHEN HN.FLAG = 'L' THEN HN.FLAG
END,
C.DT_NEW = CASE WHEN C.FLAG IN ('Y','L') THEN C.DT
WHEN C.FLAG = 'N' AND HY.FLAG = 'Y' THEN HY.DT
WHEN HN.FLAG = 'L' THEN HN.DT
END
;
SELECT * FROM CLIENT;
+------+----------+------+------------+------------+
| ID | FLAG_new | FLAG | DT_new | DT |
+------+----------+------+------------+------------+
| 1 | Y | Y | 2018-01-01 | 2018-01-01 |
| 2 | L | L | 2018-01-01 | 2018-01-01 |
| 3 | Y | N | 2018-02-01 | 2018-01-01 |
| 4 | L | K | 2018-03-01 | 2018-01-01 |
+------+----------+------+------------+------------+
4 rows in set (0.00 sec)
sql服务器
UPDATE C
SET
C.FLAG_NEW = CASE WHEN C.FLAG IN ('Y','L') THEN C.FLAG
WHEN C.FLAG = 'N' AND HY.FLAG = 'Y' THEN HY.FLAG
WHEN HN.FLAG = 'L' THEN HN.FLAG
END,
C.DT_NEW = CASE WHEN C.FLAG IN ('Y','L') THEN C.DT
WHEN C.FLAG = 'N' AND HY.FLAG = 'Y' THEN HY.DT
WHEN HN.FLAG = 'L' THEN HN.DT
END
from client c
LEFT JOIN (SELECT * FROM CLIENT_H H WHERE DT = (SELECT MIN(DT) FROM CLIENT_H H1 WHERE H1.ID = H.ID AND H1.FLAG = 'Y')) HY ON HY.ID = C.ID
LEFT JOIN (SELECT * FROM CLIENT_H H WHERE DT = (SELECT MIN(DT) FROM CLIENT_H H1 WHERE H1.ID = H.ID AND H1.FLAG = 'L')) HN ON HN.ID = C.ID