【问题标题】:Order by using subselect and grouping使用子选择和分组进行排序
【发布时间】:2016-06-15 18:34:02
【问题描述】:

这是一个小提琴:SQLFIDDLE

如果您查看我的子查询我 select location ids and order them by the sort column我希望我的最终结果集按照我在子查询中选择的 locids 的排列进行排序。 因此,例如,它应该包含对位置 3166、位置 269、位置 3572 INSTEAD of it's current results 的评论.

最后,我想限制每个位置只有一条评论(这意味着我想按评论创建日期排序),这就是我使用 locid 分组的原因。

所以,对于最终的结果集,我应该(按此顺序):

  • 评论第 16 行

  • 评论第 19 行

  • 评论第 24 行

此结果集满足以下要求(按顺序):

  • 按位置表中的排序标志排序

  • 根据排序后的位置检索到最新评论

感谢您的帮助。如果您需要任何进一步的信息,请不要犹豫。

更新

我需要的是按位置排序列排序的评论列表,然后是评论创建日期,每个位置限制为 1 个。 如果您可以通过其他方式解决此问题,请告诉我。谢谢

第二次更新

我已经开始尝试使用内部连接,但我无法获得具有最大创建日期的记录来显示。 SQLFIDDLE TWO

【问题讨论】:

  • 你的 sqlfiddle 没有加载..
  • @user2407394 很有趣。它似乎对我来说很好。尝试等到它出错,然后重试。
  • SQLFiddle 不稳定。这不是链接。
  • @JorgeCampos 我将链接交换到底部的链接网址。立即尝试。
  • 现在可以了...您可以在此处添加您预期的完整输出吗..

标签: mysql sql subquery


【解决方案1】:

!Edit:在弄清楚排序列的用途后...... 这应该是您要查找的内容:sqlfiddle.com/#!9/fa15b/9

 SELECT r.reviewid, r.locid, r.title, r.createdate, l.sort
 FROM reviews r
 INNER JOIN locations l ON l.locid = r.locid
 WHERE r.reviewid IN
     (SELECT MAX(r2.reviewid) FROM reviews r2
      GROUP BY r2.locid)
 ORDER BY l.sort

解释;我将尝试尽可能彻底地解释这一点,以便如果其他人遇到这个问题,这是有道理的。

让我们从这个查询中“需要”的内容开始:

  • 所有有评论的地点
  • 从位置表中按“排序”排序的项目
  • 每个地点的最高(表示最近的)评论(来自评论表)

我们将一次解决一个问题:

  1. 加入有评论的地点就像听起来一样简单。我们在键“locid”上的评论和位置之间运行 SQL JOIN,为我们提供了一个只有具有评论的位置的结果集(反之亦然)

  2. 接下来最简单的做法是按“排序”列排序。因此,“ORDER BY l.sort”。这给我们留下了所有评论/位置映射的完整列表。

  3. 最后一项是只挑选每个位置的最新评论。由于reviewid是按升序排列的数字,所以选择日期与review id的结果是相同的,reviewid对我来说更容易。

    • 这是子查询的用武之地;我只想获取每个位置的最新reviewid 列表(阅读:具有最高值的主键)。
    • 我使用与评论不同的别名选择 MAX(r2.reviewid),以便将其与原始列表 (r1) 进行比较。请注意,如果我将 MAX() 留在这里而不进行分组,我只会得到所有评论中最高的 reviewid(我认为在示例中是 6 个?)
    • 快完成了,我们将子查询按 r2.locid 分组,以便为​​每个单独的 locid 返回编号最高的 reviewid。
  4. 这个难题的最后一部分是从子查询中引用 reviewid,以便我们只获得我们想要的最大 id;然后在 SELECT 语句中输入您想要的任何列。

补充说明:

  • 我们不希望没有评论的地点
  • 我们不希望任何位置的倍数
  • 我也可以使用相同的逻辑而不是子查询进行自联接,但我认为 WHERE 子句更容易理解。
  • 如果您出于某种原因想要包含没有任何评论的位置,则需要使用一些奇怪的 RIGHT JOIN 逻辑。
  • 您应该实施前两项,作为练习。

【讨论】:

  • 我上面的代码适用于您的具体示例,但我认为我错过了排序列的要点,因为我们只有 3 个条目。如果您实际上“需要”涉及的排序列,那么您将需要一个联接。
  • 排序列是其排序的数值。因此,例如,如果我们按 sort col 位置 3166 排序为我的结果集中的第一个,则第二个将是位置 269,然后是最后一个位置的 3572
  • @slicks1,那么是的,你肯定需要加入。如果到我得到它的时候没有人回答,我会再看一遍。排序是唯一的列吗?
  • @slicks1 这几乎可以工作:sqlfiddle.com/#!9/fa15b/6 但抓取有问题。等一下。
  • k 请告诉我你什么时候完成
【解决方案2】:

select * 在使用group by 时完全不合适。聚合查询应该有聚合函数。

您的问题的一般答案是使用join。此类查询示例如下所示:

select r.locid, count(*), max(r.createdate)
from reviews r join
     locations l
     on r.locid = l.locid
group by locid
order by sort;

【讨论】:

  • OK 现在我需要根据最近的评论进行第二次订购,这将是评论 createdate desc。我尝试添加第二个 order by 子句,但似乎按该顺序生成记录 1,2,3 而不是 16,19,24:sqlfiddle.com/#!9/4cb5c/34/0
猜你喜欢
  • 2016-06-28
  • 2020-03-21
  • 1970-01-01
  • 2021-11-02
  • 1970-01-01
  • 1970-01-01
  • 2023-03-10
  • 1970-01-01
相关资源
最近更新 更多