概括
我目前正在开展一个项目,我必须针对底层数据库引擎查询代表用户访问的记录的最后更改。
每个用户都可以(但不是强制)拥有儿童帐户。ID_PUSR
子帐户存储在同一个数据表中,并通过表字段引用其父帐户。当帐户是主要帐户时,ID_PUSR is null
每次更改访问权限时,都会在数据库用户表中创建一条新记录,其中包含最后更新日期 ( DT_UPDT
)。
数据样本
请考虑以下几点:
create table USERS (
ID_USERS INT // Primary key
, LN_USER VARCHAR(128)
, FN_USER VARCHAR(128)
, CD_USER VARCHAR(128)
, DT_UPDT DATETIME
, ID_PUSR INT // Foreign key to USERS.ID_USERS.
)
ID_USERS CD_USER LN_USER FN_USER DT_UPDT ID_PUSR
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
808 T_PEI00 LN_USER_00 FN_USER_00 2011-01-01-00.00.00.000000 NULL
809 T_PEI00 LN_USER_00 FN_USER_00 2010-01-01-00.00.00.000000 NULL
810 T_PEI00 LN_USER_00 FN_USER_00 2009-01-01-00.00.00.000000 NULL
811 T_PEI00 LN_USER_00 FN_USER_00 2008-01-01-00.00.00.000000 NULL
812 T_PEI00 LN_USER_00 FN_USER_00 2007-01-01-00.00.00.000000 NULL
813 T_PEI00A LN_USER_00 FN_USER_00 2011-01-01-00.00.00.000000 808
814 T_PEI00A LN_USER_00 FN_USER_00 2010-01-01-00.00.00.000000 809
815 T_PEI00A LN_USER_00 FN_USER_00 2009-01-01-00.00.00.000000 810
816 T_PEI00A LN_USER_00 FN_USER_00 2008-01-01-00.00.00.000000 811
817 T_PEI00A LN_USER_00 FN_USER_00 2007-01-01-00.00.00.000000 812
818 T_MAW00 LN_USER_01 FN_USER_01 2010-01-01-00.00.00.000000 NULL
819 T_MAW00 LN_USER_01 FN_USER_01 2009-01-01-00.00.00.000000 NULL
820 T_MAW00 LN_USER_01 FN_USER_01 2008-01-01-00.00.00.000000 NULL
821 T_MAW00 LN_USER_01 FN_USER_01 2007-01-01-00.00.00.000000 NULL
822 T_VEM08 LN_USER_08 FN_USER_08 2009-01-01-00.00.00.000000 NULL
823 T_VEM08 LN_USER_08 FN_USER_08 2008-01-01-00.00.00.000000 NULL
824 T_VEM08 LN_USER_08 FN_USER_08 2007-01-01-00.00.00.000000 NULL
825 T_LAC99 LN_USER_99 FN_USER_99 2008-01-01-00.00.00.000000 NULL
826 T_LAC99 LN_USER_99 FN_USER_99 2007-01-01-00.00.00.000000 NULL
我仔细检查了两个数据库服务器中的数据表内容,我可以证明它们是相同的记录。
SQL/DB2 查询
此查询与 SQL Server 和 DB2 数据库引擎完全兼容:
with UPG as (
select ID_USERS
, CD_USER
, LN_USER
, FN_USER
, DT_UPDT
, ID_PUSR
, row_number() over (partition by CD_USER order by CD_USER desc) as ROWNUM
from USERS
) select ID_USERS
, CD_USER
, LN_USER
, FN_USER
, DT_UPDT
, ID_PUSR
, ROWNUM
from UPG
where ROWNUM = 1
order by CD_USER
不同的结果!
尽管我对上述 RDBMS 运行完全相同的查询,但我得到了不同的结果,如下所示:
IBM DB2
ID_USERS CD_USER LN_USER FN_USER DT_UPDT ID_PUSR ROWNUM
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
826 T_LAC99 LN_USER_99 FN_USER_99 2007-01-01-00.00.00.000000 NULL 1
821 T_MAW00 LN_USER_01 FN_USER_01 2007-01-01-00.00.00.000000 NULL 1
808 T_PEI00 LN_USER_00 FN_USER_00 2011-01-01-00.00.00.000000 NULL 1
814 T_PEI00A LN_USER_00 FN_USER_00 2010-01-01-00.00.00.000000 809 1
822 T_VEM08 LN_USER_08 FN_USER_08 2009-01-01-00.00.00.000000 NULL 1
在我们看到两个数据库引擎之间的差异之前,这些结果似乎很好。注意字段中的日期值DT_UPDT
。
SQL 服务器
ID_USERS CD_USER LN_USER FN_USER DT_UPDT ID_PUSR ROWNUM
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
727 T_LAC99 LN_USER_99 FN_USER_99 2008-01-01 00:00:00.000 NULL 1
720 T_MAW00 LN_USER_01 FN_USER_01 2010-01-01 00:00:00.000 NULL 1
710 T_PEI00 LN_USER_00 FN_USER_00 2011-01-01 00:00:00.000 NULL 1
715 T_PEI00A LN_USER_00 FN_USER_00 2011-01-01 00:00:00.000 710 1
724 T_VEM08 LN_USER_08 FN_USER_08 2009-01-01 00:00:00.000 NULL 1
SQL Server 中的这些结果是我将在 DB2 中使用的结果。它们代表“好”数据。至于ID_USERS
,它们只是 ID,重要的是日期。
问题
- 相同的查询如何使用两个支持 SQL ANSI 的引擎返回不同的结果?
- 是我似乎看不到的数据吗?
- DB2的
WITH...AS ()
解释与 SQL Server 有何不同?
Nota Benne:一个简单select * from USERS order by CD_USER
的揭示了相同的数据。