【问题标题】:SQL multi select with join带连接的 SQL 多选
【发布时间】:2014-04-15 05:45:17
【问题描述】:

我可以找到我的一条 sql 语句的解决方案,我想寻求您的帮助;)

假设我们有一个运动员桌,他们必须跑 100 米的距离。 每次运行后,表格会插入每次运行的运行、名称和时间:

Run Name  Time[s]
1   Joe     10
2   Joe     11
1   Jim     14
2   Jim     12

我想要做的是选择运行,名称和最快的时间,所以在这种情况下它将是 min(Time)。 但是当我使用 Min 聚合函数时,我必须按所有其他参数分组,所以它会返回所有记录...

我已经试过了。但它不起作用:

SELECT MIN(Time) AS MinTime, Name AS TimeName
        From Athletes
        group by TimeName
        LEFT JOIN  
        (Select Run, Name, Time From Athletes a)
         On 
         a.Name = TimeName, a.Time = MinTime; 

是的,它有语法错误,但这不是主要问题,因为我认为它仍然无法正常工作。

提前致谢, SQL新手

【问题讨论】:

  • 你想得到最快的运动员吗?
  • 我想问你是否打算动态或静态应用 min 函数..??

标签: sql select join left-join


【解决方案1】:

你的 SQL 查询到处都是你有一个不必要的连接,你的 group by 是在错误的地方,你的 left join 语法也不正确。我将其废弃并重写以正确使用min()

SELECT run, MIN(Time) AS MinTime,
Name AS Timename
From Athletes
group by TimeName

没有必要在同一张表上运行join,如果你知道group by需要哪些列,也不需要where子句。

在 sqlfiddle 上经过测试和工作。 http://sqlfiddle.com/#!2/13b1a/2

我建议您阅读group by 的作用以及如何正确使用join 表格。

随着表的增长,如果您不使用任何类型的 id 或键,则可以使用实际上涉及子查询的更高级的查询:

select a.run,
a1.name,
a1.Time
from athletes as a
    ,(select name,
    min(time) as Time
    from athletes
    group by name) as a1
where a.time = a1.Time
and a.name = a1.name

仍然没有理由使用join,并且子查询路由是适合您当前数据集和架构的路由。 http://sqlfiddle.com/#!2/23cb4/23

【讨论】:

  • 列“运行”在选择列表中无效,因为它不包含在聚合函数或 GROUP BY 子句中。
  • 虽然这个解决方案为 MySQL 编译,但它不符合 ANSI,并且 sql fiddle 返回一些无效数据(为 Jim 返回了错误的 run#)。用户没有指定什么数据库供应商...
  • 在 sqlfiddle 中工作。我建议你再试一次。
  • sqlfiddle 从选择中省略了run
  • @DMason,考虑到将来输入表中的数据,用第二个查询更新了我的答案。还添加了一个新的 sqlfiddle 链接。
【解决方案2】:
select Run , Name, Time from Athletes a
where Time=(select min(time) 
      from Athletes s 
      where s.Name=a.Name)

【讨论】:

    【解决方案3】:
    SELECT * 
    FROM Athletes a
    WHERE a.Time = (select min(time) from Athletes a2 where a2.Name = a.Name)
    

    这是SqlFiddle上的示例用法

    【讨论】:

      【解决方案4】:

      试试这个查询:

      SELECT r.Run, r.Name, r.Time 
      FROM (SELECT * FROM Athletes ORDER BY Time) r 
      GROUP BY r.Name
      

      【讨论】:

        【解决方案5】:

        我看到left-join 是你提问的标签之一,但没有它也可以完成。

        SELECT *
        FROM Athletes a
        WHERE a.Time = ( SELECT MIN(a2.Time) FROM Athletes a2 )
        

        请注意,如果有两个或多个跑步者并列最快时间,您可能会从查询中获得多个结果。希望这会有所帮助。

        这是获取相同信息的查询,按运动员姓名分组:

        SELECT a.*
        FROM #Athletes a
        JOIN ( SELECT a2.Name, MIN(a2.Time) Time FROM #Athletes a2  GROUP BY a2.Name) BestTimes
        ON a.Name = BestTimes.Name
        AND a.Time = BestTimes.Time
        

        【讨论】:

        • 这行不通,因为您只能找到与整个表格中单个最短时间匹配的结果,而不是运动员
        • @DLeh:也许我理解错了。但这不正是 OP 所要求的吗?
        • 它说“我想做的是选择运行,名称和最快的时间”。没有提到“按名称分组”。
        • 他的措辞有点不清楚,但他试图按跑步者的名字进行分组,所以他想要每个跑步者的时间。
        • @DLeh:好的,我向他询问了这两个问题。不确定他想要哪种方式的数据。我同意,措辞不清楚。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-04-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多