SQL: создание пар и подсчет образцов - PullRequest
0 голосов
/ 04 марта 2019

У меня есть следующая таблица (пример):

ID |LOCATION|DAY           
1  | 1      |20190301   
1  | 2      |20190301  
1  | 3      |20190301  
1  | 1      |20190302   
1  | 4      |20190302  
1  | 4      |20190305     
1  | 5      |20190302   
2  | 4      |20190301       
2  | 1      |20190301   
2  | 3      |20190303   
2  | 2      |20190305  

, где ID - это номер автомобиля, Location - это идентификатор местоположения, а время - YYYYMMDD.Я хотел бы написать SQL-запрос для подсчета числа «парных мест» для каждого carID в каждом месяце (ГГГГММ): сколько раз автомобиль существовал в местах i и j.То есть окончательные результаты должны выглядеть следующим образом:

ID|LOCATION 1|LOCATION 2|MONTH |count1|count 2  
1 | 1        |2         |201903| 2    | 1  
1 | 1        |3         |201903| 2    | 1  
1 | 1        |4         |201903| 2    | 2  
1 | 1        |5         |201903| 2    | 1   
1 | 2        |3         |201903| 1    | 1  
1 | 2        |4         |201903| 1    | 2  

, где count1 - это счет для местоположения 1, а count2 - это счет для местоположения 2, и мы построим его для каждой пары location1 и location2.

Чтобы построить пары, я попытался:

Select n1.location, n2.location
From
(
  Select location
  from table
) n1,
(
  Select location
  from table
) n2
Where n1.location < n2.location
Order by n1.location, n2.location

, но я хотел бы посчитать число для каждого местоположения (count1, count2) вместо count для пар.

Можно ли сделать это в подзапросе в SQL?Любой совет будет принят во внимание.

1 Ответ

0 голосов
/ 04 марта 2019

Это странный запрос.Вы ищете независимые подсчеты двух местоположений, но выровненные в одной строке (это странно, потому что много повторяющихся данных).

Вы можете сделать это путем агрегирования до присоединения :

with l as (
      select l.id, l.location, date_format(l.time, '%Y%m') as yyyymm,
             count(*) as cnt
      from carlocations l
      group by l.id, l.location, date_format(l.time, '%Y%m') 
     )
select l1.id, l1.location as location1, l2.location2, l1.yyyymm, l1.cnt as cnt2, l2.cnt as cnt2
from l l1 join
     l l2
     on l1.id = l2.id and l1.yyyymm = l2.yyyymm and 
        l1.location < l2.location;

with поддерживается в MySQL 8+.В более ранних версиях вам нужно было бы повторять подзапрос в предложении from.

РЕДАКТИРОВАТЬ:

Без CTE это выглядит следующим образом:

select l1.id, l1.location as location1, l2.location2, l1.yyyymm, l1.cnt as cnt2, l2.cnt as cnt2
from (select l.id, l.location, date_format(l.time, '%Y%m') as yyyymm,
             count(*) as cnt
      from carlocations l
      group by l.id, l.location, date_format(l.time, '%Y%m') 
     ) l1 join
     (select l.id, l.location, date_format(l.time, '%Y%m') as yyyymm,
             count(*) as cnt
      from carlocations l
      group by l.id, l.location, date_format(l.time, '%Y%m') 
     ) l2
     on l1.id = l2.id and l1.yyyymm = l2.yyyymm and 
        l1.location < l2.location;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...