AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 2565
Accepted
kacalapy
kacalapy
Asked: 2011-05-07 06:46:05 +0800 CST2011-05-07 06:46:05 +0800 CST 2011-05-07 06:46:05 +0800 CST

在单个存储过程中返回多个聚合的最有效方法?

  • 772

获取多个聚合结果值的最佳或最有效方法是什么?

基本上我有一个电子邮件应用程序,想要获取每种类型的文件夹(收件箱、已发送、已存档、已标记...)的所有消息数量,如下定义。

这是我在一个存储过程调用中尝试做的事情的示例。(其中 [uid] 是用户 ID)

SELECT * FROM Message
Inbox    WHERE [to]    = [uid] 
Unread    WHERE [to]    = [uid] and isread = 0
Flagged    WHERE [to]    = [uid] and isFlagged = 1
Drafts    WHERE [to]    = [uid] and isDraft = 1
Sent Messages    WHERE [from] = [uid]
Archived Messages    WHERE [to]     = [uid] and isArchived = 1
sql-server-2005 stored-procedures
  • 2 2 个回答
  • 799 Views

2 个回答

  • Voted
  1. Best Answer
    gbn
    2011-05-07T08:38:38+08:002011-05-07T08:38:38+08:00

    COUNT..CASE 是通常的方式。对于“已发送”虽然有点棘手,因为它是一个不同的 uid 过滤器,需要在消息表上进行 2 次查询

    我已经使用此构造来允许零行到/从。它避免了 OR 并为每个 CASE 添加了一个 uid 过滤器。

    每个派生表(可以写成 CTE)将只返回一行,我在 uid 上使用了 MAX 来避免 GROUP BY 以防万一有人想知道

    SELECT
        ISNULL(M.Inbox, 0) AS Inbox,
        ISNULL(M.Unread, 0) AS Unread,
        ISNULL(M.Flagged, 0) AS Flagged,
        ISNULL(M.Drafts, 0) AS Drafts,
        ISNULL(S.Sent, 0) AS Sent,
        ISNULL(M.Archived, 0) AS Archived
    FROM
        (
        SELECT
            COUNT(*) AS InBox,
            COUNT(CASE WHEN isread = 0 THEN 1 ELSE NULL END) Unread,
            COUNT(CASE WHEN isFlagged = 1 THEN 1 ELSE NULL END) Flagged,
            COUNT(CASE WHEN isDraft = 1 THEN 1 ELSE NULL END) Drafts,
            S.Sent,
            COUNT(CASE WHEN isArchived = 0 THEN 1 ELSE NULL END) Archived
        FROM
            Message
        WHERE
            [to] = [uid] 
        ) M
        FULL OUTER JOIN
        (
        SELECT COUNT(*) AS Sent
        FROM Message
        WHERE [from] = [uid]
        ) S ON 1=1
    

    编辑:

    没有 GROUP BY 的聚合将始终返回结果(请参见此处的 SO )。我忘记了。

    我更新了我的 SQL

    • 7
  2. Michael Riley - AKA Gunny
    2011-05-07T07:49:18+08:002011-05-07T07:49:18+08:00
    DECLARE @Inbox  bigint
    DECLARE @Unread bigint
    DECLARE @Flagged bigint
    /*
    MORE DECLARE STATEMENTS GO HERE
    */
    
    SET @Inbox   = SELECT Count(*) FROM MESSAGE WHERE [to] = [uid] 
    SET @Unread  = SELECT Count(*) FROM MESSAGE WHERE [to] = [uid] and isread = 0
    SET @Flagged = SELECT Count(*) FROM MESSAGE WHERE [to] = [uid] and isFlagged = 1
    
    /*
    MORE SELECT STATEMENTS GO HERE
    */
    
    SELECT
    @Inbox   as Inbox,
    @Unread  as Unread,
    @Flagged as Flagged
    
    /*
    MORE @Variables GO HERE
    */
    
    • 2

相关问题

  • 有人在实践中使用过 sqlcmd 模式吗?[关闭]

  • 是否有人使用 SQL Server 功能来创建按编号区分的存储过程组?

  • 如何在不安装新实例的情况下更改 MS SQL 2005 中的实例名称?

  • MySQL 存储例程中的动态 SQL

  • 从 SQL Server 2008 降级到 2005

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    您如何显示在 Oracle 数据库上执行的 SQL?

    • 2 个回答
  • Marko Smith

    如何选择每组的第一行?

    • 6 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    我可以查看在 SQL Server 数据库上运行的历史查询吗?

    • 6 个回答
  • Marko Smith

    如何在 PostgreSQL 中使用 currval() 来获取最后插入的 id?

    • 10 个回答
  • Marko Smith

    如何在 Mac OS X 上运行 psql?

    • 11 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Marko Smith

    将数组参数传递给存储过程

    • 12 个回答
  • Martin Hope
    Manuel Leduc PostgreSQL 多列唯一约束和 NULL 值 2011-12-28 01:10:21 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Stuart Blackler 什么时候应该将主键声明为非聚集的? 2011-11-11 13:31:59 +0800 CST
  • Martin Hope
    pedrosanta 使用 psql 列出数据库权限 2011-08-04 11:01:21 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST
  • Martin Hope
    BrunoLM Guid vs INT - 哪个更好作为主键? 2011-01-05 23:46:34 +0800 CST
  • Martin Hope
    bernd_k 什么时候应该使用唯一约束而不是唯一索引? 2011-01-05 02:32:27 +0800 CST
  • Martin Hope
    Patrick 如何优化大型数据库的 mysqldump? 2011-01-04 13:13:48 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve