我的查询有问题。
select p.id, p.firstname, p.lastname , max(s.year) as 'Last Year', min(s.year) as 'First Year', c.name from pilot p
join country on country.sigla = p.country
join circuit c on c.country_id = country.sigla
join season s
on(p.id = s.pilot_id)
group by p.id, p.firstname, p.lastname, c.name
order by p.id
表Pilot
Id (Primary Key)
Name
Table Season
表季
Year (Primary key)
Pilot_id (Foreign Key)
表国家/地区
Sigla (Primary Key)
表Cicuit
id (Primary Key)
name
Pilot表与季节和国家相关联。表格电路与国家相关联。 我想为每个飞行员显示每一行中的最后一个和第一个电路,但问题是我有重复的结果。第一个结果显示我第一个电路,副本显示我的最后一个电路。我有67个结果,我想只有40个(数据库中的飞行员总数)
答案 0 :(得分:0)
根据您的表格使用内嵌sql,如此编辑的
SELECT *
FROM (
SELECT p.id
,p.firstname
,p.lastname
,FirstCircuit = (
SELECT TOP 1 circuitname
FROM circuit c
WHERE p.id = c.id
ORDER BY year ASC
)
,LastCircuit = (
SELECT TOP 1 circuitname
FROM circuit c
WHERE p.id = c.id
ORDER BY year DESC
)
FROM pilot p
INNER JOIN country ON country.sigla = p.country
INNER JOIN season s ON (p.id = s.pilot_id)
) tbl
GROUP BY id
,firstname
,lastname
ORDER BY id
答案 1 :(得分:0)
从上面借来的答案进一步解释,因为我无法评论它。 您需要编写第一年和去年的子查询,以便为每个子查询使用不同的选择条件。第一年,您希望按年份ASC订购,以获得该列中最小的一年。对于去年,您需要按年份DESC订购才能获得该栏目中最大的一年。
SELECT *
FROM (
SELECT p.id
,p.firstname
,p.lastname
,FirstCircuit = (
SELECT TOP 1 circuitname
FROM circuit c
WHERE p.id = c.id
ORDER BY year ASC
)
,LastCircuit = (
SELECT TOP 1 circuitname
FROM circuit c
WHERE p.id = c.id
ORDER BY year DESC
)
FROM pilot p
INNER JOIN country ON country.sigla = p.country
INNER JOIN season s ON (p.id = s.pilot_id)
) tbl
GROUP BY id
,firstname
,lastname
ORDER BY id
答案 2 :(得分:0)
我怀疑问题在于加入circuit
表。
无需替换选择列表中的MIN(s.year)
和MAX(s.year)
表达式。 (尽管其他答案建议,但没有解决实际问题...获得符合规范的结果,每个飞行员只返回一个行。)
从更简单的查询开始调试...只加入pilot
表和season
表。例如:
select p.id
, p.firstname
, p.lastname
, max(s.year) as 'Last Year'
, min(s.year) as 'First Year'
from pilot p
join season s
on p.id = s.pilot_id
group by p.id, p.firstname, p.lastname
order by p.id
每pilot
最多应返回一行(假设id
表中pilot
是唯一的。)pilot
中没有的行由于内部联接,season
中的任何关联行都将被排除。
当您将连接添加到其他表(country
和circuit
)时,您可能会引入重复的行。但是这些行将被“折叠”为每个飞行员的一行。
当您在c.name
中加入GROUP BY
时,就会在您的“重复”行开始出现在结果集中。使用GROUP BY
子句中的表达式,您可以为每个飞行员返回多行。
这就是问题所在。
我们保证每位飞行员返回的行都会有c.name
的不同值。
要解决此问题,您可以从c.name
子句中删除GROUP BY
,并在选择列表中使用聚合表达式,例如MAX(c.name)
。
该查询将返回(最多)每个飞行员一行。 (同样,如果circuit
中没有与与导频关联的country
相关联的行,则会排除这些导频行。)
select p.id
, p.firstname
, p.lastname
, max(s.year) as 'Last Year'
, min(s.year) as 'First Year'
, max(c.name) as circuit_name
from pilot p
join season s
on p.id = s.pilot_id
join country
on country.sigla = p.country
join circuit c
on c.country_id = country.sigla
group by p.id, p.firstname, p.lastname
order by p.id
关于返回“每行上的第一个和最后一个电路”的一点......
如何确定哪个电路是“第一个”,哪个电路是“最后一个”?我们在表格中看到的只有两列是id
和name
。 pilot
和circuit
之间的唯一关系(显示)是通过country
表。 pilot
只有一个country
,因此导频与country
中的每个电路相关联。