mysql无限选择查询

5gfr0r5j  于 2021-06-15  发布在  Mysql
关注(0)|答案(2)|浏览(317)

我正在做一门关于关系数据库的课程,更确切地说是mysql。我们需要为一个项目创建一些select查询。这个项目与音乐有关。它有代表音乐家(音乐家)、乐队(乐队)和音乐家完成某项任务的能力的表格,比如唱歌或弹吉他(表演)。
musician 包含:

id
name
stagename
startyear

band 包含:

code
name
type ("band" or "solo")
startyear

最后是table 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 ?
提前谢谢。

798qvoo8

798qvoo81#

这是可能的,但比在from或limit中使用子查询要糟糕得多。所以我不会在现实生活中使用它:)
长话短说,你可以这样做:

SELECT
      m.id
    , m.stagename
FROM
    musician m
    INNER JOIN act a ON (
            a.musician = m.id
    )
    INNER JOIN band b ON (
            b.code = a.band
        AND b.type = 'solo'
    )
GROUP BY
      m.id
    , m.stagename
HAVING
    NOT EXISTS (
        SELECT
            *
        FROM
            act a2
            INNER JOIN band b2 ON (
                    b2.code = a2.band
                AND b2.type = 'solo'
            )
        WHERE
            a2.musician != a.musician
        GROUP BY
            a2.musician
        HAVING
            COUNT(a2.musician) > COUNT(a.musician)
    )
;

我认为您可以从查询本身理解这个想法,因为它非常简单。不过,如果你需要解释,请告诉我。
可能您的限制稍有不同,并且您不允许仅在main from part中使用子查询。
p、 我也在使用内部连接。。。因为更容易看到什么是表连接条件,什么是where条件。
p、 另外,这可能是查询中的错误,因为我没有您的数据结构,所以无法执行查询和检查。我只检查了这个想法是否适用于我的测试表。

9njqaruj

9njqaruj2#

编辑我只是重读问题;我最初的阅读遗漏了内联视图是不允许的。
我们可以避免 ORDER BY ... DESC LIMIT 1 通过使子查询成为内联视图(或者mysql术语中的“派生表”)并使用 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
       )

注意:这是问题中查询重写的演示;这并不保证此查询(或问题中的查询)返回满足任何特定规范的结果。而问题中给出的规格一点也不清楚。

相关问题