#sql #oracle #oracle10g
#sql #Oracle #oracle10g
Вопрос:
У меня есть таблица Accounts
AMOUNT| ID_CLIENT | ID_BRANCH
250 1 1
250 1 3
100 1 4
300 2 1
300 2 3
450 3 2
100 3 2
225 4 1
225 4 2
225 4 4
225 4 5
Мне нужно найти клиентов, у которых одинаковое количество в каждой ветке (например, ID_CLIENT = 2 и ID_CLIENT = 4). Я понятия не имею, как я могу это реализовать (кто-нибудь может мне помочь, пожалуйста?
Ответ №1:
Используйте два уровня агрегирования:
select client
from (select client, branch, sum(amount) as amount
from t
group by client, branch
) cb
group by client
having min(amount) = max(amount);
Я не могу сказать, может ли у вас быть несколько строк на клиента / ветку. Если нет, вам просто нужно:
select client
from t
group by client
having min(amount) = max(amount);
Комментарии:
1. @Stitch: просто предложение, хотя функция window хороша, а также правильный ответ пользователя, в этом случае использование приведенной выше логики агрессии намного лучше аналитической.
2. @Sujitmohanty30 . . . Я тоже озадачен, почему OP выбрал бы гораздо более сложные подходы к проблеме.
Ответ №2:
Вы можете использовать аналитические функции для достижения того же:
with CTE1 as
(
SELECT A.*, DENSE_RANK() OVER (PARTITION BY ID_CLIENT ORDER BY AMOUNT) DN,
COUNT(*) OVER (PARTITION BY ID_CLIENT) TOTAL_COUNT
FROM TABLE1 A ORDER BY ID_CLIENT
)
SELECT ID_CLIENT FROM
(
SELECT ID_CLIENT, SUM(DN), TOTAL_COUNT
FROM CTE1
GROUP BY ID_CLIENT, TOTAL_COUNT
HAVING SUM(DN) = TOTAL_COUNT
);
Используя First_value и Last_value:
SELECT DISTINCT ID_CLIENT FROM
(
SELECT A.*,
FIRST_VALUE(AMOUNT) OVER(PARTITION BY ID_CLIENT ORDER BY AMOUNT ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) FST_VAL,
LAST_VALUE(AMOUNT) OVER(PARTITION BY ID_CLIENT ORDER BY AMOUNT ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) LST_VAL
FROM TABLE1 A
) X WHERE FST_VAL = LST_VAL ;
Комментарии:
1. Решение прекрасное, но мое личное предложение будет заключаться в использовании aggression от @Gordon Linoff.