2017-02-14 3 views
0

Я пытаюсь оттянуть ряд деталей в зависимости от максимальной даты одного из столбцов. Выполнение простого max (date.field) не работает для моей таблицы. Изначально я решил эту проблему, используя этот запрос, который я построил, используя этот ресурс See the entry by Tom H.:Max Date/Case Statement

SELECT 
    HBM_CLIENT.CLIENT_CODE, 
    HBM_NAME.NAME AS CLIENT_NAME, 
    PART_BILL1.PART_CAT_CODE AS BILLING_CODE, 
    PART_BILL1.EMPL_UNO AS BILLING_NAME_UNO, 
    HBM_PERSNL_BILL.EMPLOYEE_NAME AS BILLING_NAME, 
    PART_BILL1.PERCENTAGE AS BILLING_PERCENTAGE 
FROM 
    HBM_CLIENT 
INNER JOIN 
    HBM_NAME ON HBM_CLIENT.NAME_UNO = HBM_NAME.NAME_UNO 
LEFT OUTER JOIN 
    TBM_CLMAT_PART AS PART_BILL1 ON PART_BILL1.CLIENT_UNO = HBM_CLIENT.CLIENT_UNO 
           AND PART_BILL1.PART_CAT_CODE = 'BILL' 
LEFT OUTER JOIN 
    TBM_CLMAT_PART AS PART_BILL2 ON PART_BILL2.CLIENT_UNO = HBM_CLIENT.CLIENT_UNO 
           AND PART_BILL2.EFF_DATE > PART_BILL1.EFF_DATE 
           AND PART_BILL1.PART_CAT_CODE = 'BILL' 
LEFT OUTER JOIN 
    HBM_PERSNL AS HBM_PERSNL_BILL ON PART_BILL1.EMPL_UNO = HBM_PERSNL_BILL.EMPL_UNO 
GROUP BY 
    HBM_CLIENT.CLIENT_CODE, HBM_NAME.NAME, 
    PART_BILL1.PART_CAT_CODE, PART_BILL1.EMPL_UNO, 
    HBM_PERSNL_BILL.EMPLOYEE_NAME, 
    PART_BILL1.PERCENTAGE, 
ORDER BY 
    HBM_CLIENT.CLIENT_CODE 

Проблемы с этим запросом является то, что по какой-то причине, он не тянет назад все результаты, и причина в том, из-за решения, которое я использовал.

Мне интересно, имеет ли смысл использовать аргумент case, но я не очень хорошо разбираюсь в операторах case.

Вот запрос, я работаю над:

`SELECT 
    HBM_CLIENT.CLIENT_CODE, 
    HBM_NAME.NAME AS CLIENT_NAME, 
    PART_BILL1.PART_CAT_CODE AS BILLING_CODE, 
    PART_BILL1.EMPL_UNO AS BILLING_NAME_UNO, 
    HBM_PERSNL_BILL.EMPLOYEE_NAME AS BILLING_NAME, 
    PART_BILL1.PERCENTAGE AS BILLING_PERCENTAGE, 
    Part_BILL1.EFF_DATE, 
CASE 
    WHEN 
    MAX(Part_BILL1.EFF_DATE) > Part_BILL1.EFF_DATE THEN max(Part_BILL1.EFF_DATE) ELSE Part_BILL1.EFF_DATE END 
FROM HBM_CLIENT 
INNER JOIN HBM_MATTER 
    ON HBM_CLIENT.CLIENT_UNO = HBM_MATTER.CLIENT_UNO 
INNER JOIN HBM_NAME 
    ON HBM_CLIENT.NAME_UNO = HBM_NAME.NAME_UNO 
LEFT OUTER JOIN TBM_CLMAT_PART AS PART_BILL1 
    ON PART_BILL1.CLIENT_UNO = HBM_CLIENT.CLIENT_UNO 
    AND PART_BILL1.PART_CAT_CODE = 'BILL' 
LEFT OUTER JOIN HBM_PERSNL AS HBM_PERSNL_BILL 
    ON PART_BILL1.EMPL_UNO = HBM_PERSNL_BILL.EMPL_UNO 
WHERE 
(HBM_CLIENT.CLIENT_CODE = '065011') 
GROUP BY 
    HBM_CLIENT.CLIENT_CODE, 
    HBM_NAME.NAME, 
    PART_BILL1.PART_CAT_CODE, 
    PART_BILL1.EMPL_UNO, 
    HBM_PERSNL_BILL.EMPLOYEE_NAME, 
    PART_BILL1.PERCENTAGE, 
    Part_BILL1.EFF_DATE 
HAVING 
(Part_BILL1.EFF_DATE = CASE 
WHEN MAX(Part_BILL1.EFF_DATE) > Part_BILL1.EFF_DATE THEN max(Part_BILL1.EFF_DATE) ELSE Part_BILL1.EFF_DATE END)` 

Он работает, но это дает мне обратно две строки вместо одной, то это не тянет только макс. Я использую T-SQL и разработку Visual Studio для записи SSRS.

Я рад ответить на любые вопросы, которые я могу. Я заранее извиняюсь, если мои объяснения не очень хорошие.

| CLIENT_CODE | CLIENT_NAME | BILLING_NAME | EFF_DATE | PERCENTAGE | 
| ------------+--------------+--------------+----------+------------| 
| 123456  | Entity, Inc. | Attorney A | 1/1/1990 |50%   | 
| 123456  | Entity, Inc. | Attorney B | 1/1/1990 |50%   | 
| 123456  | Entity, Inc. | Attorney B | 1/1/2017 |50%   | 
| 123456  | Entity, Inc. | Attorney C | 1/1/2017 |50%   | 
+0

В ссылке, которую вы указали, у вас был конкретный вопрос с данными. Вы даете тонну столов, не зная, что в них. Есть ли способ предоставить более упрощенную версию тестовых данных? Трудно помочь с такими подробными подробностями, не видя базовых данных. – djangojazz

+0

@djangojazz это достаточно разумно! Я удалил лишние вещи, так что это в основном то же самое. Теперь отображаются только те таблицы, которые необходимы для запуска запросов с выбранными мной полями. –

ответ

0

Может это не быть упрощена с помощью SELECT TOP 1 запроса с ORDER BY пунктом?

Что-то вроде этого:

SELECT TOP 1 
    HBM_CLIENT.CLIENT_CODE, 
    HBM_NAME.NAME AS CLIENT_NAME, 
    PART_BILL1.PART_CAT_CODE AS BILLING_CODE, 
    PART_BILL1.EMPL_UNO AS BILLING_NAME_UNO, 
    HBM_PERSNL_BILL.EMPLOYEE_NAME AS BILLING_NAME, 
    PART_BILL1.PERCENTAGE AS BILLING_PERCENTAGE, 
    Part_BILL1.EFF_DATE, 
    .... 
FROM HBM_CLIENT 
INNER JOIN HBM_MATTER 
    ON HBM_CLIENT.CLIENT_UNO = HBM_MATTER.CLIENT_UNO 
INNER JOIN HBM_NAME 
    ON HBM_CLIENT.NAME_UNO = HBM_NAME.NAME_UNO 
LEFT OUTER JOIN TBM_CLMAT_PART AS PART_BILL1 
    ON PART_BILL1.CLIENT_UNO = HBM_CLIENT.CLIENT_UNO 
    AND PART_BILL1.PART_CAT_CODE = 'BILL' 
LEFT OUTER JOIN HBM_PERSNL AS HBM_PERSNL_BILL 
    ON PART_BILL1.EMPL_UNO = HBM_PERSNL_BILL.EMPL_UNO 
WHERE 
(HBM_CLIENT.CLIENT_CODE = '065011') 
ORDER BY Part_BILL1.EFF_DATE DESC 

Это должно дать вам только самые последние строки по EFF_DATE, не требуя каких-либо специальных группирования или случай логики.

EDIT: На мой взгляд, лучший способ, чтобы получить результат, который вы хотите, воспользовавшись пунктом в TOP. Как правило, при написании запроса вы должны писать SELECT TOP 1 или SELECT TOP 1000, но пункт TOP также поддерживает различные функции. Вы можете использовать подзапросы, вычисления, переменные, а также функциональность WITH TIES , чтобы получить то, что вы хотите.

В вашем случае, вы хотите, чтобы запрос, чтобы вернуть любое количество строк, так долго как все они имеют один и то же EFF_DATE значения, которое также будет максимального EFF_DATE значения в таблице для данного CLIENT_CODE.

Таким образом, я бы рекомендовал просто добавить WITH TIES аргумент Оговорка TOP, чтобы получить функциональные возможности, которые вы ищете:

SELECT TOP 1 WITH TIES 
    HBM_CLIENT.CLIENT_CODE, 
    HBM_NAME.NAME AS CLIENT_NAME, 
    PART_BILL1.PART_CAT_CODE AS BILLING_CODE, 
    PART_BILL1.EMPL_UNO AS BILLING_NAME_UNO, 
    HBM_PERSNL_BILL.EMPLOYEE_NAME AS BILLING_NAME, 
    PART_BILL1.PERCENTAGE AS BILLING_PERCENTAGE, 
    Part_BILL1.EFF_DATE, 
    .... 
FROM HBM_CLIENT 
INNER JOIN HBM_MATTER 
    ON HBM_CLIENT.CLIENT_UNO = HBM_MATTER.CLIENT_UNO 
INNER JOIN HBM_NAME 
    ON HBM_CLIENT.NAME_UNO = HBM_NAME.NAME_UNO 
LEFT OUTER JOIN TBM_CLMAT_PART AS PART_BILL1 
    ON PART_BILL1.CLIENT_UNO = HBM_CLIENT.CLIENT_UNO 
    AND PART_BILL1.PART_CAT_CODE = 'BILL' 
LEFT OUTER JOIN HBM_PERSNL AS HBM_PERSNL_BILL 
    ON PART_BILL1.EMPL_UNO = HBM_PERSNL_BILL.EMPL_UNO 
WHERE 
(HBM_CLIENT.CLIENT_CODE = '065011') 
ORDER BY Part_BILL1.EFF_DATE DESC 

полное объяснение различных видов использования пункта TOP может быть найдено here.

чтобы кратко объяснить, то WITH TIES аргумент означает, что вы хотите запрос вернуть TOP X строк набора данных, основанных на значении (-ах) в пункте ORDER BY - в вашем случае, EFF_DATE.Так что, если есть две строки с одинаковым значением в EFF_DATE или три ряда, или пять сто, все они будут возвращены, потому что вы эффективно поиск не для TOP 1 ROW, а для TOP 1 VALUE of EFF_DATE

Надеюсь, это поможет.

+0

Если я правильно помню, это не сработает, потому что в тот же день могут быть два адвоката. Есть поле под названием Part_bill1.percentage. В этой колонке у каждого из этих адвокатов будет 50-процентный кредит. Я нахожусь на мобильном телефоне, поэтому я могу пересмотреть таблицу выше, но представьте себе, что в 1999 году адвокат и адвокат b получают 50 50 кредитов. В 2017 году адвокат b уходит в отставку, поэтому адвокат добавляет адвоката ç в качестве нового содиректора. Поэтому в этом случае мне нужно оттянуть два ряда адвоката и адвоката. Я попробую ваше предложение, как только смогу, но я думаю, что топ и макс были первыми, что я сделал. –

+0

Подтверждено, это не работает для моей ситуации. –

+0

@ T.Meyer Я не понял из вашего вопроса, что вы искали несколько строк. Вы специально заявили, что хотите «ряд деталей, основанный на максимальной дате одного из столбцов». В описанном вами примере вы говорите об агрегированной строке - т. Е. Вы хотите, чтобы два разных адвоката перечислялись в одной строке, которые должны быть выбраны максимальной датой? – 3BK