首页 > 解决方案 > 获取总数和前 3 列

问题描述

我有以下 SQL 查询:

SELECT TOP 3 accounts.username
    ,COUNT(accounts.username) AS count
FROM relationships
JOIN accounts ON relationships.account = accounts.id
WHERE relationships.following = 4
    AND relationships.account IN (
        SELECT relationships.following
        FROM relationships
        WHERE relationships.account = 8
        );

我想返回accounts.username 和前3 个accounts.username 的总数(没有特别的顺序)。可惜不能共存accounts.usernameCOUNT(accounts.username)该查询可以很好地删除其中一个。我不想使用不同的选择主体两次发送请求。计数列可以跨越到 1000+,所以我更喜欢在 SQL 中而不是在代码中计算它。

当前查询返回的错误Column 'accounts.username' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.没有带我到任何地方,这与其他问题不同,因为我不想使用“分组依据”子句。有没有办法做到这一点FOR JSON AUTO

所需的输出可能是:

+-------+----------+
| count | username |
+-------+----------+
| 1551  | simon1   |
| 1551  | simon2   |
| 1551  | simon3   |
+-------+----------+

或者

+----------------------------------------------------------------+
| JSON_F52E2B61-18A1-11d1-B105-00805F49916B                      |
+----------------------------------------------------------------+
| [{"count": 1551, "usernames": ["simon1", "simon2", "simon3"]}] |
+----------------------------------------------------------------+

标签: sqlsql-servertsql

解决方案


如果要username在结果集中的附加列中显示满足过滤条件(并且其中不为空)的总行数,则可以使用窗口函数:

SELECT TOP 3
    a.username,
    COUNT(a.username) OVER() AS cnt
FROM relationships r
JOIN accounts a ON r.account = a.id
WHERE 
    r.following = 4
    AND EXISTS (
        SELECT 1 FROM relationships t1 WHERE r1.account = 8 AND r1.following = r.account
    )
;

旁注:

  • 如果username不可为空,则使用COUNT(*)而不是COUNT(a.username):这更有效,因为它不需要数据库检查每个值是否为空
  • 表别名使查询更易于编写、读取和维护
  • 我通常更喜欢EXISTSIN但这主要是一个口味问题,因为这两种技术都应该适合您的用例)

推荐阅读