2015-05-14 2 views
0

У меня есть запрос, в котором я пытаюсь найти строки, которые содержат максимальное значение в определенном поле. Я пробовал max (имя_поля), но он возвращает все строки.Функция max() с неработающими соединениями - DB2 SQL

SELECT CMNT.ID, MAX(CMNT.SEQ_NBR) AS SEQ, CMNT.VER_NBR AS VERSION 
FROM 
CUSTOMER_CMNT AS CMNT 
INNER JOIN CUSTOMER_PROD AS PRODUCT ON PRODUCT.PRODUCT_ID = CMNT.BALE_ID 
LEFT JOIN CUSTOMER_LOAN LOAN ON (PRODUCT.LOAN_ID = LOAN.LOAN_ID) AND (PRODUCT.START_YR = LOAN.START_YR) AND (PRODUCT.ST_CD = LOAN.ST_CD) AND (PRODUCT.CNTY_CD = LOAN.CNTY_CD) 
WHERE CMNT.ID > 0 AND PRODUCT.START_YR = 2013 AND LOAN.LOAN_NBR = 17124 
GROUP BY CMNT.VER_NBR, CMNT.SEQ_NBR, CMNT.ID, CMNT.CMNT_TXT 

выход

+----------------+------+---------+ 
| CMNT.ID  | SEQ | VERSION | 
+----------------+------+---------+ 
133340000101373 2  1 
133340000101374 2  1 
133340000101373 3  1 
133340000101374 3  1 
133340000101373 4  1 
133340000101374 4  1 
133340000101373 1  2 
133340000101374 1  2 
133340000101373 1  3 
133340000101374 1  3 
133340000101373 2  3 
133340000101374 2  3 

Но, ожидаемые ряды (макс (SEQ_NBR)):

+----------------+------+---------+ 
| CMNT.ID  | SEQ | VERSION | 
+----------------+------+---------+ 
133340000101373 4  1 
133340000101374 4  1 

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

SELECT CMNT.ID, MAX(CMNT.SEQ_NBR) AS SEQ, CMNT.VER_NBR AS VERSION 
FROM 
CUSTOMER_CMNT AS CMNT 
INNER JOIN CUSTOMER_PROD AS PRODUCT ON PRODUCT.PRODUCT_ID = CMNT.BALE_ID 
LEFT JOIN CUSTOMER_LOAN LOAN ON (PRODUCT.LOAN_ID = LOAN.LOAN_ID) AND (PRODUCT.START_YR = LOAN.START_YR) AND (PRODUCT.ST_CD = LOAN.ST_CD) AND (PRODUCT.CNTY_CD = LOAN.CNTY_CD) 
WHERE CMNT.ID > 0 AND PRODUCT.START_YR = 2013 AND LOAN.LOAN_NBR = 17124 
CMNT.SEQ_NBR = (select max(CMNT.SEQ_NBR) from 
FROM 
CUSTOMER_CMNT AS CMNT 
INNER JOIN CUSTOMER_PROD AS PRODUCT ON PRODUCT.PRODUCT_ID = CMNT.BALE_ID 
LEFT JOIN CUSTOMER_LOAN LOAN ON (PRODUCT.LOAN_ID = LOAN.LOAN_ID) AND (PRODUCT.START_YR = LOAN.START_YR) AND (PRODUCT.ST_CD = LOAN.ST_CD) AND (PRODUCT.CNTY_CD = LOAN.CNTY_CD) 
WHERE CMNT.ID > 0 AND PRODUCT.START_YR = 2013 AND LOAN.LOAN_NBR = 17124) 

Из-за подзапроса этот запрос поменялся дольше. Есть ли способ сократить/улучшить этот запрос?

+0

Вероятно, не имеет отношения к СОЕДИНЕНИЯМ. Первые группы запросов более чем желательны для осуществления желаемого агрегата; тот же результат был бы, если бы были удалены все критерии JOIN и был запрошен только файл CMNT. Второй запрос не является синтаксически правильным, и этот запрос не может привести к * правильным * результатам, даже если скалярный подзадача был как-то закодирован, но правильно как предикат ANDed. Кажется вероятным, данные выборок просто появляются, чтобы получить ожидаемый результат; эффективно, а не намеренно; Отсутствие GROUP BY, подсегмент выбирает MAX (SEQ_NBR) независимо от чего-либо еще. – CRPence

ответ

0

Как насчет этого? Не уверен, что если он работает лучше, хотя ...

declare @data table (cmnt_id bigint, seq int, version int) 

insert into @data 
values (133340000101373, 2, 1), (133340000101374, 2, 1), (133340000101373, 3, 1), (133340000101374, 3, 1), (133340000101373, 4, 1), (133340000101374, 4, 1), (133340000101373, 1, 2), (133340000101374, 1, 2), (133340000101373, 1, 3), (133340000101374, 1, 3), (133340000101373, 2, 3), (133340000101374, 2, 3) 

select d.cmnt_id, d.seq, d.version 
from @data d 
inner join (
    select cmnt_id, max(seq) as target_seq 
    from @data 
    group by cmnt_id 
    ) x on x.cmnt_id = d.cmnt_id 
    and d.seq = x.target_seq 
order by d.cmnt_id 
0

В идеале, вы холодный запуск запроса с использованием Visual Explain инструмента, и он будет рекомендовать индексы, которые по его мнению не хватает.

Вне этого, я бы определенно рекомендовал следующие индексы/Кейс:

CUSTOMER_CMNT 
    index1 => BALE_ID 
    index2 => ID, SEQ_NBR 

CUSTOMER_PROD 
    index1 => START_YR 
    index2 => LOAN_ID, START_YR, ST_CD, CNTY_CD 

CUSTOMER_LOAN 
    index1 => LOAN_NBR 
    index2 => LOAN_ID, START_YR, ST_CD, CNTY_CD 

HTH!

Смежные вопросы