Как найти строку с равным значением?

#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.