SQL, как получить столбец только один раз, связанный с несколькими записями одного и того же значения в другом столбце?

#sql

#sql

Вопрос:

Предположим, что после таблицы с именем ‘SalesRecords’

 Name     City        Sales     Item
John     London      10        X
John     London      5         Y
John     New York    7         Z
Charles  London      5         A
George   New York    10        A
Geroge   New York    5         X
  

Здесь Джон — один и тот же человек в Лондоне и в Нью-Йорке, я хочу получить человека, который работает более чем в одном городе, а также в каких городах они работают, и соответствующее количество продаж, которые они совершили в этом городе. Как показано ниже —

 Name     City        Sales
John     London      15
John     New York    7
  

Как добиться этого с помощью SQL?

Ответ №1:

Вы можете использовать exists перед агрегацией:

 SELECT Name, City, SUM(Sales) as TotalSales
FROM SalesRecords sr
WHERE EXISTS (SELECT 1
              FROM SalesRecords sr
              WHERE sr2.Name = sr.Name AND sr2.City <> sr.City
             )
GROUP BY Name, City;
  

Или вы можете использовать оконные функции:

 SELECT nc.*
FROM (SELECT Name, City, SUM(Sales) as TotalSales,
             COUNT(*) OVER (PARTITION BY Name) as Num_Cities
      FROM SalesRecords sr
      GROUP BY Name, City
     ) nc
WHERE Num_Cities >= 2;
  

Ответ №2:

Я использую общую таблицу выражений для получения значения TotalSales, а затем в запросе я фильтрую человека, который работал более чем в одном городе.

 ;with sales as
(
    SELECT 
        Name,
        City, 
        SUM(Sales) as TotalSales
    FROM SalesRecords
    GROUP BY Name, City
)
select name, city, TotalSales from sales s
where exists(select * from sales s2 where s2.Name = s.Name and s.City <> s2.City)
  

Ответ №3:

Вам нужно использовать GROUP BY по имени и городу:

 SELECT a.Name, a.City, SUM(a.Sales) AS Sales
FROM yourTable a

INNER JOIN (
            SELECT NAME, COUNT(*)
            FROM
                (
                SELECT Name, City
                FROM yourTable
                GROUP BY Name, City
                )
            HAVING COUNT(*) > 1
            ) b ON A.name = b.name

GROUP BY a.Name, a.City
  

Комментарии:

1. Это также приведет к получению Джорджа, который торгует только в Нью-Йорке, который должен быть исключен. Должен быть выбран только тот человек, который работает в нескольких городах.

2. Верно! Отредактировано, чтобы включить предложение HAVING

3. Он выбирает следующим образом «Название города Итоговые продажи Джон Лондон 15 Джордж Нью-Йорк 15 «

4. О да, сложнее, чем я думал сначала. В третий раз повезло присоединиться к подзапросу для идентификации кратных …? Отредактированный ответ.