MySQL不确定聚合函数
我有一个多对多表的函数MySQL不确定聚合函数,mysql,group-by,min,Mysql,Group By,Min,我有一个多对多表的函数 table Actor ----------- Actorid Fullname table entertainment ------------------------- Entertainmentid Name Date Actor_entertainment ------------------------- Entertainmentid Actorid 我需要选择所有演员的名字,每个演员最早的娱乐日期和演员的名字 我构建这个查询: S
table Actor
-----------
Actorid Fullname
table entertainment
-------------------------
Entertainmentid Name Date
Actor_entertainment
-------------------------
Entertainmentid Actorid
我需要选择所有演员的名字,每个演员最早的娱乐日期和演员的名字
我构建这个查询:
SELECT
a.fullname
, c.Name
, MIN(c.Date)
FROM Actor a
INNER JOIN Actor_entertainment b on b.Actorid = a.Actorid
INNER JOIN entertainment c ON c.entertainmentID = b.entertainmentID
GROUP BY
a.Fullname
查询工作正常,但我不确定MIN函数选择的日期是否正确。你能读一下这个问题,告诉我我哪里错了吗?准确地说,有可能出错吗
谢谢。是的,将返回
c.Date
的最小值。只要日期
列的数据类型为日期
,日期时间
,时间戳
,或者该列中存储的值为规范格式,那么这将是“最早的日期”。。。较低的值对应较早的日期
但是,为c.Name
表达式返回的值是不确定的。也就是说,不能保证为该表达式返回的值将来自返回最小日期值的同一行
(其他数据库将返回该SQL语句的错误,在“非聚合”时犹豫不前)表达式出现在选择列表中,而不出现在GROUP BY
子句中。MySQL为GROUP BY提供了一个非标准扩展,允许执行此查询。可以修改MySQL的行为,以禁用此扩展,方法是将SQL\u模式
设置为仅包含GROUP BY
)
有几种方法可以获取与最早日期关联的名称
对于返回的少量行以及可用的适当索引,使用相关子查询是可行的:
SELECT a.fullname
, ( SELECT c.Name
FROM entertainment c
JOIN Actor_entertainment b
ON b.entertainmentID = c.entertainmentID
WHERE b.Actorid = a.Actorid
ORDER BY c.Date ASC, c.Name ASC
LIMIT 1
) AS `Name`
, ( SELECT c.Date
FROM entertainment c
JOIN Actor_entertainment b
ON b.entertainmentID = c.entertainmentID
WHERE b.Actorid = a.Actorid
ORDER BY c.Date ASC, c.Name ASC
LIMIT 1
) AS `Date`
FROM Actor a
ORDER BY a.fullname
另一种方法是获取最早的日期,然后执行联接以查找对应于该最早日期的行。如果Actor中给定行有多行具有相同的“最小”日期,这将返回所有这些行:
SELECT da.fullname
, dc.Name
, dc.Date
FROM ( SELECT a.actorid
, MIN(c.Date) AS min_date
FROM Actor a
JOIN Actor_entertainment b
ON b.Actorid = a.Actorid
JOIN entertainment c
ON c.entertainmentID = b.entertainmentID
GROUP BY a.actorid
) d
JOIN Actor da
ON da.actorid = d.actorid
JOIN Actor_entertainment db
ON db.Actorid = d.Actorid
JOIN entertainment dc
ON dc.entertainmentID = db.entertainmentID
AND dc.Date = d.min_date
使用变量,您可以根据日期为每个艺术家创建排名,然后只需选择每个艺术家的第一个
另请参见不要使用别名A,B,C
i使用A,AE,E
帮助理解查询
SELECT ArtistName,
EntertainmentName,
Date
FROM (
SELECT
A.fullname ArtistName
, E.Name EntertainmentName
, E.Date
, (@rank := if(@prev_artist = A.fullname,
@rank + 1, -- increase rank
if(@prev_artist := A.fullname, --reset rank
0,
0
)
)
) as ranking
FROM Actor A
INNER JOIN Actor_entertainment AE
on A.Actorid = AE.Actorid
INNER JOIN entertainment E
ON AE.entertainmentID = E.entertainmentID
CROSS JOIN (select @rank := 0, @prev_artist := '') params
ORDER BY A.Actorid, E.Date
) T
WHERE ranking = 1
你会得到正确的日期。问题是你是否能得到正确的娱乐。name
。如果数据库管理系统是Oracle,则如果任何组中有多个名称,则会出现错误。感谢您提供有关命名表的建议。