Проблема с фрейминговым запросом SQL

#sql #sql-server #sql-server-2008

#sql #sql-сервер #sql-server-2008

Вопрос:

Я запускаю SQL-запрос, который возвращает только часть всех данных. Другими словами, данные ‘обрамлены.’ У меня есть часть «ПОРЯДОК (ORDER BY)», и по какой-то причине эта часть работает не все время. Иногда я получаю то, что ожидаю, а в других случаях нет.

Запрос:

 SELECT 
    *
FROM
(
    SELECT
        ROW_NUMBER() OVER(ORDER BY [datetime] DESC, timeMicroSec DESC) AS rowNum,
        ...
    FROM
        ...
    WHERE
        ...
) AS TempTbl
WHERE
    rowNum BETWEEN @startRow AND @endRow;
  

Весь запрос данных работает, когда он не оформлен, и я использую предложение ‘ORDER BY’ в конце. На изображении ниже столбец [datetime] и столбец [timeMicroSec] объединены с помощью конкатенации строк.
Просмотр упорядочения результатов этого запроса

Как вы можете видеть, порядок полностью нарушен. Буду признателен за любую помощь.

Комментарии:

1. Не ORDER BY rowNum делает то, что вам нужно?

2. Это не так. Я собираю данные из нескольких источников, чтобы они не были упорядочены в таблице по дате, времени / микронам (что мне и нужно). Кроме того, я полагаю, что rowNum всегда будет от 1 до XX, независимо от того, в каком порядке находятся базовые данные.

3. @Chris — DOH! Пропустил это. Комментарий удален.

Ответ №1:

Когда вы приводите DateTime в качестве Varchar, это изменяет способ упорядочивания столбца SQL Server. Он больше не будет упорядочивать его в хронологическом порядке, а вместо этого просто как старую строку.

Если типом данных является DateTime, вы получите следующий порядок сортировки по убыванию:

 01/11/2011
02/22/2010
  

Первая дата хронологически более поздняя… но если тип данных — Varchar … он будет отсортирован как:

 02/22/2010
01/11/2011
  

Потому что строка «02» идет после «01»… фактическое значение даты на данный момент не имеет значения. Когда вы объединяете свою дату с Timemicrosecutive, вы меняете сортировку на сортировку по переменной.

Как говорили другие … если вы упорядочите по RowNum вместо вашей объединенной строки, вы получите хронологический порядок.

Комментарии:

1. Это было мое подозрение; однако я думал, что предложение OVER () было оценено первым. Преобразование в строку выполняется в инструкции select с помощью функции ‘dbo.sdrFormatDate([datetime], timeMicroSec)’

2. Продолжаю искать, и я понимаю, почему иногда я получаю правильный результат, а другие нет. Это должна быть строка. Можете ли вы объяснить, почему rowNum что-либо исправит? Не будет ли это всегда упорядочиваться от 1 до XX, независимо от того, как упорядочены данные в строках?

3. Вы правы, предложение OVER вычисляется первым, но внешний запрос выглядит так, как будто он сортируется как varchar для меня… Есть ли во внешнем запросе предложение ORDER BY?

4. Вы создали rowNum, используя ORDER BY [datetime] DESC, timeMicroSec DESC , поэтому rowNum упорядочен в хронологическом порядке, а не как varchar. Упорядочивание по числу строк упорядочит ваши результаты в хронологическом порядке, даже если вы больше не возвращаете DateTime во внешнем select.

5. Я вижу, что результаты моего запроса работают сейчас, просто они не отображаются прямо в моей таблице. Это еще одна проблема. Я ценю пациентов и помощь. Теперь я точно понимаю, что делает запрос!

Ответ №2:

ORDER BY rowNum

в качестве последней части вашего запроса ваша проблема будет устранена.

Комментарии:

1. rowNum всегда будет упорядочен в TempTbl, такова природа запроса. Что мне нужно, так это упорядочить данные до того, как rowNum будет присвоен строкам.

2. @Nik — row_number выполняет order обработку данных с помощью [datetime] DESC, timeMicroSec DESC при присвоении чисел, поэтому я не понимаю, почему вы не можете упорядочить результат по этим?

3. Извините, вы меня совсем запутали, rowNum равен 1 для самой новой даты / времени и XX для самой старой. Сортировка по romNum должна привести к обратному хронологическому порядку. Вы хотите упорядочить результаты в подзапросе?

4. @Chris — Martin прав, я просто не понимал, что делал OVER (ORDER BY ..).

5. @Nik — хорошо, вы должны прочитать об этом, делает сложные запросы очень простыми (особенно с PARTITION ).