SQL Server / DB2:相同的查询返回不同的结果?

时间:2011-02-10 00:38:50

标签: sql-server-2005 db2 resultset with-statement

摘要

我目前正在开发一个项目,我必须针对底层数据库引擎查询代表用户访问的记录的最后更改。

每个用户可能并且不是必须拥有子帐户。子帐户存储在同一数据表中,并通过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 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

SQL Server中的这些结果是我将在DB2中使用的结果。它们代表了“好”的数据。至于ID_USERS,它们只是ID,重要的是日期。

问题

  1. 使用两个支持SQL ANSI的引擎,同一查询如何返回不同的结果?
  2. 这是否与我似乎没有看到的数据有关?
  3. DB2解释的WITH...AS ()如何与SQL Server不同?
  4. Nota Benne:一个简单的select * from USERS order by CD_USER显示相同的数据。

1 个答案:

答案 0 :(得分:3)

您的查询对于关系是不确定的。

row_number() over (partition by CD_USER order by CD_USER desc) as ROWNUM

没有在每个分区中定义任何特定的row_numbering。如果您希望两个RDBMS都以独特的方式返回相同的结果顺序,那么就没有关系和确定性结果。