我正在针对关系数据库MySQL做一门课程,以更加具体。我们需要为项目创建一些SELECT查询。该项目与音乐有关。它具有代表音乐家(音乐家),乐队(乐队)和音乐家完成特定任务的能力的表格,例如唱歌或弹吉他(表演)。
表musician
包含:
id
name
stagename
startyear
表band
包含:
code
name
type ("band" or "solo")
startyear
最后,表act
包含:
band (foreign key to code of "band" table)
musician (foreign key to id of "musician" table)
hability (guitarist, singer, like that... and a foreign key to another table)
earnings
我对两个练习有疑问,第一个要求选择音乐家id
和stagename
,他们在类型为solo
的乐队中参与更多的演出。
我对第一个解决方案是:
SELECT ma.id, ma.stagename
FROM musician ma, act d, band ba
WHERE ma.id = d.musician
AND ba.code = d.band
AND ba.type = "solo"
GROUP BY ma.id, ma.stagename
HAVING COUNT(ma.id) = (SELECT COUNT(d2.musician) AS count
FROM act d2, band ba2
WHERE d2.band = ba2.code
AND ba2.type = "solo"
GROUP BY d2.musician
ORDER BY count DESC
LIMIT 1);
第二个与最后一个非常相似。我们需要为每一个startyear
选择一个音乐家,他们可以做更多的动作,并具有相应的动作数量以及其声望的最大值和最小值,分别是id
和stagename
。这是我的解决方案:
SELECT ma.startyear, ma.id, ma.stagename, COUNT(ma.id) AS NumActs, MIN(d.earnings), MAX(d.earnings)
FROM musician ma, act d, band ba
WHERE ma.id = d.musician
AND ba.code = d.band
AND ba.type = "solo"
GROUP BY ma.year, ma.id, ma.stagename
HAVING COUNT(ma.id) = (SELECT COUNT(d2.musician) AS count
FROM act d2, band ba2
WHERE d2.band = ba2.code
AND ba2.type = "solo"
GROUP BY d2.musician
ORDER BY count DESC
LIMIT 1);
使用我的虚拟数据得到的结果是完美的,但是我的老师告诉我们,我们应该避免使用LIMIT
选项,但这是我们获得最高数字的唯一方法,至少现在就知道了。
在FROM
语句之后,我已经看到很多子查询可以解决此问题,但是,对于本项目,我们不能在FROM
内部使用子查询。如果没有LIMIT
,这真的有可能吗?
谢谢。
答案 0 :(得分:1)
可能,但比from或limit中的子查询差得多。所以我永远不会在现实生活中使用它:)
长话短说,您可以执行以下操作:
source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}"
PREFIX "Implementation"
FILES ${SRC_BUILD_FILES})
我认为您可以从查询本身中理解这个想法,因为它非常简单。但是,请告诉我是否需要解释。
您的限制可能会稍有不同,并且您不允许仅在主FROM部分中使用子查询。
P.S。我还使用INNER JOIN ... ON语法,因为它更容易了解什么是表联接条件以及什么是条件条件。
P.P.S。查询可能有误,因为我没有您的数据结构,因此无法执行查询和检查。我只检查了这个想法是否适用于我的测试桌。
答案 1 :(得分:0)
编辑,我只是重新阅读了问题;我的初始阅读错过了不允许使用内联视图。
我们可以通过使子查询成为内联视图(或MySQL术语中的“派生表”)并使用ORDER BY ... DESC LIMIT 1
聚合来避免使用MAX()
构造。
作为一个简单的演示,该查询:
SELECT b.foo
FROM bar b
ORDER
BY b.foo DESC
LIMIT 1
可以用以下查询模拟:
SELECT MAX(c.foo) AS foo
FROM (
SELECT b.foo
FROM bar b
) c
重写问题中第一个查询的示例
SELECT ma.id
, ma.stagename
FROM musician ma
JOIN act d
ON d.musician = ma.id
JOIN band ba
ON ba.code = d.band
WHERE ba.type = 'solo'
GROUP
BY ma.id
, ma.stagename
HAVING COUNT(ma.id)
= ( SELECT MAX(c.count)
FROM (
SELECT COUNT(d2.musician) AS count
FROM act d2
JOIN band ba2
ON ba2.code = d2.band
WHERE ba2.type = 'solo'
GROUP
BY d2.musician
) c
)
注意:这是对问题中查询的重写的演示;这不能保证此查询(或问题中的查询)被保证返回满足任何特定规范的结果。问题中给出的规范还不清楚。