Сводка
В настоящее время я работаю над проектом, в котором мне нужно выполнить запрос к базовому ядру базы данных для последних изменений записей, которые представляют доступ пользователей.
Каждый пользователь может и являетсяне обязательно, иметь детей аккаунты.Дочерние учетные записи хранятся в одной и той же таблице данных со ссылкой на своего родителя через поле таблицы 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
Различные результаты!
Несмотря на то, что я выполняю один и тот же точно такой же запрос к вышеупомянутой СУБД, я получаю разные результаты следующим образом:
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
, то это просто идентификаторы, важны даты.
Вопросы
- Как один и тот же запрос может возвращать разные результаты, используя два механизма с поддержкой SQL ANSI?
- Это что-то с базой данных, которую я не вижу?
- Как интерпретируется DB2
WITH...AS ()
, который будет отличаться от SQL Server?
Nota Benne: простой select * from USERS order by CD_USER
показывает те же данные.