用一条SQL完成数据表的行统计

本文介绍了一种针对特定软件项目中库存查询的需求,提供了三种不同的SQL查询方法来计算产品的库存数量,包括使用子查询、IIF函数及分组统计等技术。
By Ben

作者的一个软件项目的查询系统需求:

有数据表:
名称    数量   状态
-----------------------
产品A    10     进货
产品A    20     销售
产品B    20     进货
 
要查询结果为:
产品名称   库存数量
-----------------------
产品A        -10 
产品B         20
解决方法一:
SELECT
DISTINCT 名称,
(ISNULL((select SUM(A.数量) from 库存表 A WHERE A.名称 = 库存表.名称 AND A.状态='进货'), 0)
-
ISNULL((select SUM(A.数量) from 库存表 A WHERE A.名称 = 库存表.名称  AND A.状态='销售'), 0)) AS 库存数量
FROM
库存表

解决方法二(Access):
SELECT 名称,Sum(IIF(状态='进货',1,-1) * 数量) as  库存数量 From 库存表 Group By 名称

解决方法三(Access):
SELECT 名称,Sum(IIF(状态='进货',数量,0)-IIF(状态='销货',数量,0)) as  库存数量 From 库存表 Group By 名称




Trackback: http://tb.blog.youkuaiyun.com/TrackBack.aspx?PostId=130708


### 单条SQL查询实现多维度统计的方法 在数据库操作中,通过单条 SQL 查询实现多维度统计数据是一种常见的需求。以下是几种方法及其适用场景: #### 方法一:使用 `CASE` 表达式进分组统计 这种方法适用于简单的多维度统计情况。可以通过 `SUM(CASE WHEN ... THEN ... END)` 的方式来分别统计不同的维度。 ```sql SELECT SUM(CASE WHEN stu_name = '张三' THEN 1 ELSE 0 END) AS zhangsan_count, SUM(CASE WHEN STU_ADDRESS = '浙江' THEN 1 ELSE 0 END) AS zhejiang_count, SUM(CASE WHEN STU_AGE = 23 THEN 1 ELSE 0 END) AS age_23_count FROM student; ``` 此方法利用了 `CASE` 表达式的灵活性[^1],可以针对每一行数据根据不同条件进分类计数,并最终汇总结果。 --- #### 方法二:使用 `IF` 函数简化逻辑表达 对于某些支持 `IF` 函数的数据库(如 MySQL),可以直接使用 `IF` 来替代复杂的 `CASE` 结构,从而让代码更加简洁明了。 ```sql SELECT COUNT(IF(stu_name = '张三', 1, NULL)) AS zhangsan_count, COUNT(IF(STU_ADDRESS = '浙江', 1, NULL)) AS zhejiang_count, COUNT(IF(STU_AGE = 23, 1, NULL)) AS age_23_count FROM student; ``` 这种方式同样能够完成多维度统计的任务,但在语法上更为直观[^3]。 --- #### 方法三:借助 `GROUP BY CUBE` 实现更复杂的数据透视 当需要对多个字段的不同组合进全面统计时,可以考虑使用 `CUBE` 运算符。`CUBE` 能够自动生成所有可能的分组组合,适合用于构建多维数据分析模型。 ```sql SELECT stu_name, STU_ADDRESS, STU_AGE, COUNT(*) AS record_count FROM student GROUP BY CUBE(stu_name, STU_ADDRESS, STU_AGE); ``` 上述查询会返回学生姓名、地址和年龄的所有可能组合以及对应的记录数量[^4]。注意,这种做法可能会生成大量冗余数据,因此需谨慎评估性能影响。 --- #### 方法四:跨表联合查询与聚合函数结合 如果涉及多张表之间的关联,则可以在左连接的基础上应用聚合函数完成多维度统计。例如,在 PostgreSQL 中处理类似问题时可采用如下形式: ```sql SELECT COALESCE(SUM(t.click_count::NUMERIC) / NULLIF(SUM(t.show_count), 0), 0) AS click_rate, COUNT(DISTINCT t.user_id) AS unique_users, ... FROM table1 t LEFT JOIN app_projects t2 ON t2.id = COALESCE(t.project_id, t1.project_id) WHERE (t.date BETWEEN '2024-06-05 00:00:00.0' AND '2024-06-12 00:00:00.0' OR t1.date BETWEEN '2024-06-05 00:00:00.0' AND '2024-06-12 00:00:00.0'); ``` 这里的关键在于正确设置连接条件并合理运用聚合函数以避免潜在错误[^2]。 --- ### 总结 以上四种方法各有优劣,具体选择取决于实际业务需求和技术环境约束。简单情况下推荐使用 **方法一或方法二**;而对于高度灵活的需求来说,**方法三** 和 **方法四** 更具优势。 问题
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值