简体   繁体   English

SQL:进行配对和计数样本

[英]SQL: Making pairs and count samples

I have the following table (example): 我有下表(示例):

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  

where ID is car number, Location is location id, and time is YYYYMMDD. 其中ID是车号,位置是位置ID,时间是YYYYMMDD。 I would like to write a SQL query to count the number for ''pair-wise locations'' for each carID in each month(YYYYMM): how many times the car existed in location i and j. 我想编写一个SQL查询来计算每个月每个carID的“配对位置”的数量(YYYYMM):汽车在位置i和j中存在的次数。 That is, the final results should look like 也就是说,最终结果应该是这样的

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  

where count1 is the count for location 1 and count2 is the count for location 2, and we construct this for every pair of location1 and location2. 其中count1是位置1的计数,count2是位置2的计数,我们为每对location1和location2构造它。

To construct the pairs, I tried: 为了构建对,我试过:

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

but I would like to count the number for each location (count1, count2) instead of count for pairs. 但我想计算每个位置的数字(count1,count2)而不是对数的计数。

Can I do this in sub-query in SQL? 我可以在SQL中的子查询中执行此操作吗? Any advice would be appreciated. 任何意见,将不胜感激。

This is an odd request. 这是一个奇怪的要求。 You are looking for independent counts of the two locations, but aligned in one row (it is odd because there is lots of repeated data). 您正在寻找两个位置的独立计数,但是在一行中对齐(这很奇怪,因为有大量重复数据)。

You can do this by aggregated before joining: 您可以加入之前通过聚合执行此操作:

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;

The with is supported in MySQL 8+. MySQL 8+支持with In earlier versions, you would need to repeat the subquery in the from clause. 在早期版本中,您需要在from子句中重复子查询。

EDIT: 编辑:

Without CTEs, this looks like: 没有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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM