如何获得平均穿越的城市数

How to get the average number of cities crossed

我是数据库的初学者。我需要写一些 SQL 查询。

table 是:

远征(id, number, id_captain, id_ship, id_heros)
城市(id, name)
英雄联盟(id, family_name, first_name)
步骤(id, index, id_expedition, id_city)

示例数据:

'Table expedition'

id 个数 id_captain id_ship id_hero
1 1 1 10 8
2 2 2 1 5
3 3 1 8 3
4 4 10 9 6
5 5 5 7 4
6 6 6 5 4
7 7 7 3 7
8 8 8 2 8
9 9 9 1 3
10 10 1 4 2
11 11 6 3 1
12 12 8 6 1
13 13 5 8 6
14 14 4 9 9
15 15 3 10 4
16 16 10 2 2
17 17 9 3 3
18 18 8 7 7
19 19 9 8 10
20 20 7 2 2

table 'heros'

id family_name first_name
1 familyname1 名字 1
2 familyname2 名字 2
3 familyname3 名字 3
4 familyname4 名字 4
5 familyname5 名字 5
6 familyname6 firstname6
7 familyname7 名字 7
8 familyname8 名字 8
9 familyname9 名字 9
10 familyname10 名字 10

query1:旅行最少的家庭(以姓氏为准)(最少的城市不同路口)。

我已经为第一个查询做了这个:

select expedition.id, id_hero, heros.family_name as Famille_expedition, count(distinct id_city) as city_count
from expedition, step, heros 
where expedition.id=step.id and expedition.id_hero=heros.id
group by id_hero
having city_count = 
(select count(distinct id_city) as min_city_count
from expedition, step
where expedition.id=step.id
group by id_hero
order by min_city_count asc
limit 1);  

query2:一次探险穿越城市的平均值

第二个不知道怎么回答

那么,首先问问自己,您需要哪些信息来回答您的问题?

从你的问题来看,我想说平均交叉次数只是 steps table 中所有条目的总和除以 expeditions 的数量,因为在每一步中,访问一个城市,所有访问的平均值就是您要查找的内容:

SELECT (
       (SELECT COUNT(s.id_city)
          FROM step AS s) /
       (SELECT COUNT(e.id)
          FROM expedition AS e) ) AS total_average__cities

也就是说,这取决于您如何准确定义城市数量交汇。想象以下 table step 的示例数据:

id idx id_expedition id_city
1 1 1 1
2 2 1 5
3 3 1 3
4 1 2 5
5 2 2 9
6 1 3 8
7 2 3 5
8 3 3 9
9 4 3 5
10 5 3 8

table列出了三个探险的步骤。探险 1 从一个城市经过另一个城市到达第三个城市。 Expedition 2 直接从一个城市前往另一个城市。探险 3 穿过几个城市,沿途访问一个城市两次,还 returns 到达它开始的城市。

所有这些步骤的平均城市数是 (3 + 2 + 5 [cities in all steps]) / 3 [expeditions] = 3.3333。也就是上面查询的结果。

现在,如果您将城市数量定义为唯一个城市每个探险 , 远征 3 只访问了 3 个城市而不是 5 个。那么你的平均值计算为 (3 + 2 + 3 [unique cities/expedition in all steps]) / 3 [expeditions] = 2.6666。根据查询需要计算每个探险中的不同城市,然后再计算平均值:

SELECT (
       (SELECT SUM(cnt) FROM (SELECT COUNT(DISTINCT s.id_city) AS cnt
                                FROM step AS s
                            GROUP BY s.id_expedition) t) /
       (SELECT COUNT(e.id)
          FROM expedition AS e) ) AS total_average__cities

现在,如果您将穿越定义为只覆盖沿途个城市,探险1只穿越1个城市,探险2穿越none 完全没有。

那么您的查询也需要看起来不同。您需要过滤所有城市以排除每次探险的第一个和最后一个。子查询可能如下所示:

SELECT s.* FROM step s
JOIN (   SELECT id_expedition, 
                MAX(idx) AS max_idx, 
                MIN(idx) AS min_idx
           FROM step s
       GROUP BY id_expedition) minmax
  ON s.id_expedition = minmax.id_expedition
 AND s.idx > minmax.min_idx
 AND s.idx < minmax.max_idx

因此,如果您希望穿越的城市数不包括起点和终点,则平均值将计算为 (1 + 0 + 3 [intermediate cities in all steps]) / 3 [expeditions] = 1.3333。相应的查询将是

SELECT (
       (SELECT COUNT(s.id_city) 
          FROM step s
          JOIN (   SELECT id_expedition, 
                          MAX(idx) as max_idx, 
                          MIN(idx) as min_idx
                     FROM step s
                 GROUP BY id_expedition) minmax 
            ON s.id_expedition = minmax.id_expedition
           AND s.idx > minmax.min_idx
           AND s.idx < minmax.max_idx) /
       (SELECT COUNT(e.id)
          FROM expedition AS e) ) AS total_average__cities

最后,如果您想 排除开始和停止 并且 只想计算独特的城市,您的平均值将被计算作为 (1 + 0 + 2 [unique intermediate cities in all steps]) / 3 [expeditions] = 1。以下查询结合了上述两种方法:

SELECT (
       (SELECT SUM(cnt) FROM (SELECT COUNT(DISTINCT id_city) AS cnt
                                FROM step s
                                JOIN (   SELECT id_expedition, 
                                                MAX(idx) AS max_idx, 
                                                MIN(idx) AS min_idx
                                           FROM step s
                                       GROUP BY id_expedition) minmax
                                  ON s.id_expedition = minmax.id_expedition
                                 AND s.idx > minmax.min_idx 
                                 AND s.idx < minmax.max_idx
                            GROUP BY s.id_expedition) t) /
       (SELECT COUNT(e.id)
          FROM expedition AS e) ) AS total_average_cities

您可以在 this db<>fiddle 中测试所有这些查询。