让我们说例如我有表:
-----------------------------------------------
| id | name | age | hair_color | delete_flag |
-----------------------------------------------
| 1 | Jhon | 20 | black | 0 |
-----------------------------------------------
现在当一个属性被改变时,让我们说Jhon现在是21我们插入一个新的记录形式Jhon并且我们将之前的delete_flag设置为1.这是一个奇怪的工作流程但是我试图保持它的简单示例。
我的目标是找出Jhon的哪个属性发生了变化。在更复杂的问题版本中,当我们有一个Person表,Property_type表和Properties表时,在最后一个表中看起来像:
属性
-----------------------------------------------------------
| id | person_id | property_type_id | value | delete_flag |
-----------------------------------------------------------
| .... |
-----------------------------------------------------------
这里Jhon的所有道具都是不同的行,当Jhon例如改变他的头发颜色所有以前的道具(所有行有person_id = jhons_id)被设置为删除(delete_flag = 1)并且所有道具再次添加时只有差异:头发颜色道具不同(只有1行差异)。
现在我想知道哪个道具已被改变?他改变了头发的颜色,还是已经过了21年。我尝试使用属性和属性之间的某种JOIN来执行此操作,但没有设法获得结果。
PS:我无法添加像'changed'(0/1)这样的新列。
答案 0 :(得分:2)
尝试使用windows函数lead / lag
表格强>
ID NAME AGE HAIR_ DELETE_FLAG
---------- ---- ---------- ----- ---------------------------------------
1 John 20 black 1
2 John 21 black 0
select id, name, age, hair_color,
case
when age <> prev_age then 'Age Changed'
when hair_color <> prev_hair_color then 'Hair Changed'
else 'Nothing Changes just Rearranges' end as changes,
prev_age, prev_hair_color
from (
select id, name, age, hair_color,
lead(age) over (partition by name order by id desc) prev_age,
lead(hair_color) over (partition by name order by id desc) prev_hair_color,
delete_flag
from t
) t1
where delete_flag = 0;
<强> OUPUT 强>
ID NAME AGE HAIR_COLOR CHANGES PREV_AGE PREV_HAIR_COLOR
2 John 21 black Age Changed 20 black
答案 1 :(得分:0)
我猜你在这个过程中为John分配了一个新的ID,因为你的目标似乎在某个点上有两条John记录(其中一条记录的delete_flag为true),那么你应该有另一种发现约翰的方法,我认为它是name
列。
我有两种建议方法:
您可以在属性表中使用MINUS
来查找旧约翰和新约翰之间已更改的属性:
SELECT prop_id
FROM property
WHERE person_id = oldJOHNid
MINUS
SELECT prop_id
FROM property
WHERE person_id = newJOHNid
在用户表中,您可以比较所有属性列,以查找所有新/旧记录或特定用户的差异
SELECT TOLD.name, TOLD.id AS old_id, TNEW.id AS new_id,
(CASE WHEN TOLD.age = TNEW.age THEN 'Age identical' ELSE 'Age Changed' END) age_status,
...
(CASE WHEN TOLD.hair = TNEW.hair THEN 'Hair identical' ELSE 'Hair changed' END) hair_status
FROM usertable TOLD,
usertable TNEW
WHERE TOLD.name = TNEW.name
AND TOLD.name='John' -- optional