【问题标题】:How can I both count total result and group them?我怎样才能计算总结果并将它们分组?
【发布时间】:2017-06-15 13:07:27
【问题描述】:

这是我的桌子:

// posts
+----+-----------+--------------------+------------+--------+
| id |   title   |        body        |  author_id | amount |
+----+-----------+--------------------+------------+--------+
| 1  | post1     | somthing           | 2543       | 5000   |
| 2  | post2     | something else     | 4352       | NULL   |
| 3  | post3     | whatever           | 1563       | 1200   |
| 4  | post4     | test context       | 7234       | NULL   |
| 5  | post5     | anything ...       | 4352       | NULL   |
+----+-----------+--------------------+------------+--------+

我也有这两个疑问:

SELECT COUNT(*), COUNT(amount) FROM posts
+----------+---------------+
| COUNT(*) | COUNT(amount) |
+----------+---------------+
| 5        | 2             |
+----------+---------------+

SELECT * FROM posts ORDER BY id LIMIT 0,2
+----+-----------+--------------------+------------+--------+
| id |   title   |        body        |  author_id | amount |
+----+-----------+--------------------+------------+--------+
| 1  | post1     | somthing           | 2543       | 5000   |
| 2  | post2     | something else     | 4352       | NULL   |
+----+-----------+--------------------+------------+--------+

现在我想结合这两个查询,这是预期的结果:

+----+-----------+--------------------+------------+--------+----------+---------------+
| id |   title   |        body        |  author_id | amount | COUNT(*) | COUNT(amount) |
+----+-----------+--------------------+------------+--------+----------+---------------+
| 1  | post1     | somthing           | 2543       | 5000   | 5        | 2             |
| 2  | post2     | something else     | 4352       | NULL   | 5        | 2             |
+----+-----------+--------------------+------------+--------+----------+---------------+

我怎样才能做到这一点?这是我迄今为止尝试过的错误,它总是返回一行:

SELECT x.*, COUNT(*), COUNT(amount)
FROM (
    SELECT * FROM posts ORDER BY id
) x
LIMIT 0,2

【问题讨论】:

  • 将第二个查询交叉连接到第一个。

标签: mysql sql arrays group-by


【解决方案1】:

如果我正确理解您的需求。交叉加入查询应该可以解决问题..

SELECT * 
FROM posts p
CROSS JOIN (SELECT COUNT(*) cnt, COUNT(amount) cntamt FROM posts) t
ORDER BY p.id 
LIMIT 0,2

ALTERNATE 可能(未测试)...但又是一个子查询...但只有 1 个 where 子句。

SELECT id, title, body, author_id, max(cnt) cnt, max(cntAmount) cntAmount
FROM (SELECT id
           , title
           , body
           , author_id
           , @cnt=@cnt+1 as cnt
           , case when Amount is not null then @cntamt:=@cntAmt+1 else @cntAmt end as cntAmount
      FROM posts p
      CROSS JOIN (SELECT @cnt:=0,@cntAmt:=0) t
      GROUP BY id, title, body, author_id) Z
ORDER BY z.id 
LIMIT 0,2

【讨论】:

  • in reality 这两个查询有一个相同且复杂的where 子句,我正在尝试提高性能并匹配一次结果。但在你的情况下,你仍然选择了两次。
  • 如果 mySQL 支持窗口/分析函数,那么这可以在 1 个查询中实现。但是,它没有。
  • 谢谢。只是为什么在select 语句中使用所有列的名称?为什么不只是*
  • 习惯。因为我必须按列分组,所以我在选择中列出了它们。此外,如果表结构发生变化(新列)或列的顺序,我的选择不会受到影响。
【解决方案2】:

您可以使用CROSS JOIN 来完成此操作。像这样:

SELECT 
    posts.*,
    tbl.nbr,
    tbl.nbrAmount 
FROM 
    posts 
CROSS JOIN 
    (SELECT COUNT(*) as nbr, COUNT(amount) as nbrAmount FROM posts) AS tbl
ORDER BY id LIMIT 0,2

【讨论】:

  • in reality 这两个查询有一个相同且复杂的where 子句,我正在尝试提高性能并匹配一次结果。但在你的情况下,你仍然选择了两次。
【解决方案3】:

使用 Join 你可以组合这个。

SELECT p1.*,p2.* FROM posts AS p1
LEFT JOIN (
   SELECT COUNT(*), COUNT(amount) FROM posts
) AS p2 ON 1=1
ORDER BY p1.id LIMIT 0,2

【讨论】:

    猜你喜欢
    • 2019-08-18
    • 2011-07-11
    • 1970-01-01
    • 1970-01-01
    • 2022-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多