2016-10-27 3 views
0

Я пытаюсь сортировать отчет в том порядке, в котором конечный пользователь хочет его обработать.Order By with Case Statement Не работает как ожидается

Во-первых, он должен быть отсортирован по следующим сценариям:

  1. String_Field заселена, но COMMENT_DATE является нулевым
  2. String_Field не заполняется
  3. Оба String_Field и COMMENT_DATE заселены

И тогда он должен быть отсортирован по старению Task_Date.

Я добавил следующее к моему ORDER BY:

(case when max(table1.comment_date) is null then 2 else 1 end) DESC, 
(case when table1.string_field is null then 2 else 1 end) ASC, 
max(table2.task_date) ASC 

А потом я добавил их к моему SELECT, также:

(case when max(table1.comment_date) is null then 2 else 1 end) as sort1 
(case when table1.string_field is null then 2 else 1 end) as sort2 
max(table2.task_date) as task_date 

Что я получаю, и не могу понять, для жизнь мне почему это (отредактирован, чтобы показать высокий/низкий при каждом изменении):

Picture of Sample Results

Я пробовал кастинг, перемещая агрегацию вокруг и добавляя значения вместе, и я все еще получаю эти 2s, застрявшие посредине невидимого раскола в 1s.

Если это имеет значение, я придумываю значения для string_field через Query Union Query, а comment_date присоединяется к string_field во втором CTE, прежде чем второй CTE (таблица1) останется соединенным с таблицей, содержащей task_date (таблица2). Вы можете иметь string_field без comment_date, но никогда не comment_date без string_field. Должна быть задана запись task_date для записи в отчете. Отчет сгруппирован по строковому полю.

Я нахожусь на SQL Server 2008 R2.

Заранее благодарим за вашу помощь!


Edited добавить Квази-SQL:

WITH 
old_new_string AS (
    SELECT 
    tablea.old_string_field, 
    tablea.string_field, 
    'A' as match_type 
    FROM 
    tablea 
    WHERE 
    tablea.old_string_field is not null 
    UNION ALL 
    SELECT 
    B1.string_field AS old_string_field, 
    B2.string_field AS string_field, 
    'B1' as match_type 
    FROM 
    tableb B1 
    INNER JOIN tableb B2 ON B1.string_field <> B2.string_field AND B1.id1 = B2.id1 
    WHERE 
    B1.id1 is not null 
    UNION ALL 
    SELECT 
    B1.string_field AS old_string_field, 
    B2.string_field AS string_field, 
    'B2' as match_type 
    FROM 
    tableb B1 
    INNER JOIN tableb B2 ON B1.string_field <> B2.string_field AND B1.id1 = B2.id2 
    WHERE 
    B1.id1 is not null), 
table1 AS (
    SELECT TOP 100 PERCENT /* Enables order by to improve join performance */ 
    old_new_string.old_string_field, 
    old_new_string.string_field, 
    old_new_string.match_type, 
    comment_date = (SELECT max(comment_table.comment_date) FROM comment_table WHERE old_new_string.string_field = comment_table.string_field and comment_table.comment_code = '001') 
    FROM 
    old_new_string 
    ORDER BY 
    old_new_string.old_string_field) 
SELECT 
tablez.string_field as old_string_field, 
max(table2.task_date) as task_date, 
min(cast(getdate() - table2.task_date as bigint)) as Aging 
table1.string_field as new_string_field, 
max(table1.match_type) as match_type, 
max(table1.comment_date) as comment_date, 
sort_order1 = (case when max(table1.comment_date) is null then 2 else 1 end), 
sort_order2 = (case when table1.string_field is null then 2 else 1 end) 
FROM 
tablez 
INNER JOIN table2 ON tablez.string_field = table2.string_field 
LEFT JOIN table1 on tablez.string_field = table1.old_string_field 
Where 
table2.task_date IS NOT NULL 
Group By 
tablez.string_field, table1.new_string_field 
ORDER BY 
(case when max(table1.comment_date) is null then 2 else 1 end) DESC, 
(case when table1.string_field is null then 2 else 1 end) ASC, 
max(table2.task_date) ASC 
+0

Вы действительно хотите, чтобы мы, чтобы понять это все из? Добавление кода действительно поможет много ... И некоторые примеры данных и ожидаемый результат тоже. – NickyvV

+0

Я больше ищут указатели - например, я не думал, что соединение может повлиять на ORDER BY - это неправильно? Есть ли какая-то эзотерическая проблема с использованием операторов case в порядке? Или это может повлиять на агрегацию? – ImagineMBE

+0

Данные, с которыми я работаю, очень чувствительны - я бы даже не захотел опубликовать SQL для проблем безопасности. – ImagineMBE

ответ

0
ORDER BY 
    case when max(table1.comment_date) is null then 2 else 0 end 
+ case when table1.string_field is null then 0 else 1 end DESC 

или

ORDER BY CASE 
    WHEN max(table1.comment_date) is null and table1.string_field is not null 
     THEN 0 
    WHEN table1.string_field is null 
     THEN 1 
    WHEN max(table1.comment_date) is not null and table1.string_field is not null 
     THEN 2 
     ELSE 3 END 
+0

Спасибо, но такое же поведение с обоими! :( – ImagineMBE

+0

Я подозреваю, что 'max (table1.comment_date)' NULL гораздо чаще, чем вы думаете ... возможно, почти для каждой записи. Если ** любое ** значение 'table1.comment_date' в группе равно" null " , тогда полная 'max (table1.comment_date)' для этой строки/группы будет 'null'. В результате все записи имеют одинаковый приоритет в предложении ORDER BY, и в этом случае Sql Server может свободно использовать из запроса вышел естественный порядок кластеризации. –

+0

Если бы это было так, это решило бы как нуль последовательно, не так ли? И я бы увидел, что это отразилось на моей сортировке1? Я редактировал свое оригинальное сообщение, чтобы показать полный SQL - я изменил имена таблиц и полей и удалил много дополнительных полей/объединений. – ImagineMBE