从 SQLite 到 SAP ASE/SQL 服务器需要一些关于查询重写的帮助
Going from SQLite to SAP ASE/SQL Server need some assistance on query rewrite
我在 SQLite 中编写了以下查询,它工作正常,但发现办公室使用 SAP ASE(Sybase SQL 服务器)并且它没有显示相同的结果。
select
dm04_maf.mcn,
dm04_maf.wc_cd,
dm04_maf.buno_serno,
max(dm12_maf_note.maf_note) as Last_Note,
dm12_maf_note.note_dttm as Time_of_Note,
dm12_maf_note.orignr
from
dm04_maf
left join
dm12_maf_note on dm04_maf.mcn = dm12_maf_note.mcn
where dm04_maf.ty_maf_cd = 'TD'
group by dm04_maf.mcn
我认为它没有正确执行分组,因为它没有给我每个 mcn(主键)的最后一个音符,而是给我每个 mcn 的每个音符。
如有任何指导,我们将不胜感激。
具有ROW_NUMBER()
window功能:
select t.mcn, t.wc_cd, t.buno_serno,
t.maf_note as Last_Note,
t.note_dttm as Time_of_Note,
t.orignr
from (
select d04.mcn, d04.wc_cd, d04.buno_serno,
d12.maf_note, d12.note_dttm, d12.orignr,
row_number() over (partition by d04.mcn order by d12.maf_note desc) rn
from dm04_maf d04 left join dm12_maf_note d12
on d04.mcn = d12.mcn
where d04.ty_maf_cd = 'TD'
) t
where t.rn = 1
符合 ANSI 的 group by
查询将在 group by
子句中包含所有 non-aggregate 列(来自 select
/projection 列表)。虽然许多 RDBMS 将允许 non-ANSI 兼容的 group by
查询(就像在这个问题中一样),但每个 RDBMS 选择如何处理所述 non-ANSI 兼容的 group by
查询是有待商榷的(即,无法保证在不同的 RDBMS 中获得相同的结果。
一些假设:
- OP 提到只想显示
'last note'
;现在我们假设 max(maf_note)
足以确定给定 mcn
值 的 'last note'
- 其他 non-aggregate 列(例如,
wc_cd
、buno_serno
、note_dttm
和 orignr
)应该来自生成 last note
= 最大值(maf_note)`
由于 SAP (Sybase) ASE 既不支持 windows 函数也不支持 ROW_NUMBER()
,一个想法是使用 sub-query 找到 'last note'
然后加入这进入主查询以提取所需值的其余部分,例如:
select dm1.mcn,
dm1.wc_cd,
dm1.buno_serno,
dt.Last_Note,
dmn1.note_dttm as Time_of_Note,
dmn1.orignr
from dm04_maf dm1
left
join dm12_maf_note dmn1
on dm1.mcn = dmn1.mcn
join (select dm2.mcn,
max(dmn2.maf_note) as Last_Note
from dm04_maf dm2
join dm12_maf_note dmn2
on dm2.mcn = dmn2.mcn
where dm2.ty_maf_cd = 'TD'
group by dm2.mcn
) dt
on dm1.mcn = dt.mcn
and dmn1.maf_note = dt.Last_Note
where dm1.ty_maf_cd = 'TD'
注释:
- 额外的
dm1.ty_maf_cd = 'TD'
可能是多余的;将由 OP 决定是保留还是删除
- (显然)可能需要返回并根据假设的有效性进行调整and/or 更新问题
我在 SQLite 中编写了以下查询,它工作正常,但发现办公室使用 SAP ASE(Sybase SQL 服务器)并且它没有显示相同的结果。
select
dm04_maf.mcn,
dm04_maf.wc_cd,
dm04_maf.buno_serno,
max(dm12_maf_note.maf_note) as Last_Note,
dm12_maf_note.note_dttm as Time_of_Note,
dm12_maf_note.orignr
from
dm04_maf
left join
dm12_maf_note on dm04_maf.mcn = dm12_maf_note.mcn
where dm04_maf.ty_maf_cd = 'TD'
group by dm04_maf.mcn
我认为它没有正确执行分组,因为它没有给我每个 mcn(主键)的最后一个音符,而是给我每个 mcn 的每个音符。
如有任何指导,我们将不胜感激。
具有ROW_NUMBER()
window功能:
select t.mcn, t.wc_cd, t.buno_serno,
t.maf_note as Last_Note,
t.note_dttm as Time_of_Note,
t.orignr
from (
select d04.mcn, d04.wc_cd, d04.buno_serno,
d12.maf_note, d12.note_dttm, d12.orignr,
row_number() over (partition by d04.mcn order by d12.maf_note desc) rn
from dm04_maf d04 left join dm12_maf_note d12
on d04.mcn = d12.mcn
where d04.ty_maf_cd = 'TD'
) t
where t.rn = 1
符合 ANSI 的 group by
查询将在 group by
子句中包含所有 non-aggregate 列(来自 select
/projection 列表)。虽然许多 RDBMS 将允许 non-ANSI 兼容的 group by
查询(就像在这个问题中一样),但每个 RDBMS 选择如何处理所述 non-ANSI 兼容的 group by
查询是有待商榷的(即,无法保证在不同的 RDBMS 中获得相同的结果。
一些假设:
- OP 提到只想显示
'last note'
;现在我们假设max(maf_note)
足以确定给定mcn
值 的 - 其他 non-aggregate 列(例如,
wc_cd
、buno_serno
、note_dttm
和orignr
)应该来自生成last note
= 最大值(maf_note)`
'last note'
由于 SAP (Sybase) ASE 既不支持 windows 函数也不支持 ROW_NUMBER()
,一个想法是使用 sub-query 找到 'last note'
然后加入这进入主查询以提取所需值的其余部分,例如:
select dm1.mcn,
dm1.wc_cd,
dm1.buno_serno,
dt.Last_Note,
dmn1.note_dttm as Time_of_Note,
dmn1.orignr
from dm04_maf dm1
left
join dm12_maf_note dmn1
on dm1.mcn = dmn1.mcn
join (select dm2.mcn,
max(dmn2.maf_note) as Last_Note
from dm04_maf dm2
join dm12_maf_note dmn2
on dm2.mcn = dmn2.mcn
where dm2.ty_maf_cd = 'TD'
group by dm2.mcn
) dt
on dm1.mcn = dt.mcn
and dmn1.maf_note = dt.Last_Note
where dm1.ty_maf_cd = 'TD'
注释:
- 额外的
dm1.ty_maf_cd = 'TD'
可能是多余的;将由 OP 决定是保留还是删除 - (显然)可能需要返回并根据假设的有效性进行调整and/or 更新问题