SQL查询仅适用于一列,添加第二列后即停止工作

时间:2018-10-13 14:44:45

标签: sql group-by inner-join greatest-n-per-group

我正在尝试使此查询正常工作,但我没有设法使其正常工作,这是到目前为止我已经设法完成的工作:

select c.EID
from certified c
    inner join aircrafts a ON c.AID = a.AID
group by c.EID 
HAVING count(c.EID)  >= 3 and MAX(a.CRUISINGRANGE);

结果:

EID
'141582651'

'142519864'

'269734834'

'390487451'

'552455318'

'556784565'

'567354612'

'573284895'

如您所见,为了获得最大巡航距离,我与飞机工作台进行了内部连接,从获得认证的我算起,并返回可以驾驶3架以上飞机的飞行员。

现在我的问题是,我似乎无法在我的选择中添加a.AID来显示它,这是我尝试过的操作:

select c.EID, a.AID
from certified c
    inner join aircrafts a ON c.AID = a.AID
group by c.EID, a.AID
HAVING count(c.EID)  >= 3 and MAX(a.CRUISINGRANGE);

结果:

EID援助

0行

预期结果:

EID          AID

'141582651'  '6475'

'142519864'  '8430'

'269734834'   '8430'

'390487451'   '7120'

'552455318'   '3383'

'556784565'   '7120'

'567354612'   '8430'

'573284895'   '7120'

但是我尝试这样做却得到0行。

DATA SAMPLE: 
Certified: 
EID        AID
142519864   1
269734834   1
550156548   1
567354612   1
11564812    2
141582651   2
142519864   2
242518965   2
269734834   2
552455318   2
556784565   2


AIRCRAFTS
AID    ANAME         CRUISING RANGE
1   Boeing 747-400  8430
2   Boeing 737-800  3383
3   Airbus A340-300 7120
4   British Aerospace Jetstream 41  1502
5   Embraer ERJ-145 1530
6   SAAB 340    2128
7   Piper Archer III    520
8   Tupolev 154 4103
9   Lockheed L1011  6900
10  Boeing 757-300  4010
11  Boeing 777-300  6441
12  Boeing 767-400ER    6475
13  Airbus A320 2605
14  Airbus A319 1805
15  Boeing 727  1504
16  Schwitzer 2-33  30
123 Airbus  1000
302 Boeing  5000
306 Jet01   5000
378 Airbus380   8000

1 个答案:

答案 0 :(得分:1)

您的问题确实很难理解;您似乎并没有以一致和连贯的方式说明您想要的内容。通过阅读评论,您似乎想知道:

每位飞行员(额定3架或以上飞机)飞行的最远距离。

因此,您期望得到飞行员EID的列表,以及飞行员可能飞行的所有飞机上的最大巡航距离(来自飞机表)。飞行员必须至少能够飞行3架飞机。

步骤:

建立飞行员名单以及他们所额定的飞机可以飞行的距离:

SELECT c.EID, a.cruising_range
FROM certified c INNER JOIN aircrafts a ON c.AID = a.AID

改进查询以计算每个飞行员的额定值和最大巡航距离(飞行员可以驾驶飞机,飞机有一定的范围,因此,当飞行员驾驶飞机时,飞行员可以有一定的范围):

SELECT c.EID, COUNT(*) as count_ratings, MAX(a.cruising_range) max_range
FROM certified c INNER JOIN aircrafts a ON c.AID = a.AID
GROUP BY c.EID --per pilot

改进查询以仅选择能够飞行至少3架飞机的飞行员:

SELECT c.EID, max_range FROM
(
  SELECT c.EID, COUNT(*) as count_ratings, MAX(a.cruising_range) max_range
  FROM certified c INNER JOIN aircrafts a ON c.AID = a.AID
  GROUP BY c.EID --per pilot
) pilot_ranges
WHERE
  pilot_ranges.count_ratings >= 3

我本可以使用HAVING:

SELECT c.EID, MAX(a.cruising_range) max_range
FROM certified c INNER JOIN aircrafts a ON c.AID = a.AID
GROUP BY c.EID 
HAVING COUNT(*) >= 3

但是有时候这样做是有好处的,它以分步而不是一次尝试的方式一步一步地直观地布置查询,并使用子查询从心理上形成数据列表,然后对其进行更改,过滤,添加。

查询优化器可能会在内部重写这些查询,因此无论如何它们最终都将以相同的方式执行,因此对人类的理解和未来维护都是有益的

编辑:这是一个查询,其中列出了每个飞行员-飞机组合的EID和AID,其中飞行员能够飞行3架以上飞机:

SELECT c.EID, a.AID FROM
(
  SELECT c.EID
  FROM certified c
  GROUP BY c.EID 
  HAVING count(*) >= 3
) find_pilots_can_fly_atleast_three
INNER JOIN certified c ON c.EID = find_pilots_can_fly_atleast_three.EID
INNER JOIN aircrafts a ON c.AID = a.AID

首先,您生成一个有趣的飞行员列表-这是find_pilots_can_fly_atleast_three的子类别,然后我们将这些数据重新添加到经过认证的飞机上。我们最后列出了可以驾驶3架飞机的飞行员名单,并获得了有关飞机的详细信息

您可能一口气尝试做太多事情。分组时,会丢失某些数据位。在对飞行员进行分组以便找到可以飞行3架以上飞机的人员时,我们必须丢失飞机ID,而仅保留飞行员ID。如果您尝试保留飞机ID(因为要保留),最终将得到只有1个计数的组,因为每个飞行员飞机组合都是唯一的。因此,我们将飞机ID丢失为一个汇总(计数),并保留飞行员ID。这有助于我们找出每个飞行员可以飞行多少架飞机。 为了找出这些飞行员​​可以乘坐的 飞机,我们必须将“找到3+”查询中的飞行员ID加入到飞行员飞机列表(经认证的表格)中,然后将其扩展到飞机驾驶员名单

始终记住,允许您将表与其自身连接,并且确实在这种情况下至关重要。如果您有一个充满地址的表格,其中包含您居住在该日期的日期,那么要查找最新的表格,您将获得一个查询your_id, max(lived_there_until_date,但您无法保留任何其他地址数据-想要最新记录的日期。然后,如果您想要该最新行中的其余数据,则将刚刚执行的查询加入到地址表中,以检索具有最新lived_there_until日期的整个行