SQL Server/DB2: Same query returns different results?
Summary
I'm currently working on a project where I have to query against the underlying database engine for last changes of records that represents users accesses.
Each user may, and is not mandatory to, have children accounts. Children accounts are stored within the same data table with a reference to its parent through the ID_PUSR
table field. When the account is a primary, ID_PUSR is null
Each time an acces is changed, a new record is then created in the database users table, with a last update date (DT_UPDT
).
Data Sample
Please consider the following:
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_U开发者_开发技巧SER_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
I double-checked the data table content within both database servers and I can certify that they are identical records.
SQL/DB2 Query
This query is fully compatible with both SQL Server and DB2 database engines:
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
Different Results!
Despite the fact that I'm running the same exact identical query against the above-mentioned RDBMS, I obtain different results as follows:
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
These results appears to be good until we can see the difference between the two database engines. Notice the date values in the DT_UPDT
field.
SQL Server
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
These results here in SQL Server are the one with which I shall come in DB2. They represent the "good" datum. As for the ID_USERS
, they are just ID's, what matters are the dates.
Questions
- How can the same query returns different results using two SQL ANSI capable engines?
- Is it something with the datum which I don't seem to see?
- How is the
WITH...AS ()
interpreted by DB2 that shall differ from SQL Server?
Nota Benne: A simple select * from USERS order by CD_USER
reveals the same data.
Your query is undeterministic for ties.
row_number() over (partition by CD_USER order by CD_USER desc) as ROWNUM
doesn't define any particular row_numbering within each partition. If you want both RDBMS's to return the same results order by something unique so there are no ties and deterministic results.
精彩评论