MS SQL 挑战问题

简介: 群里面有位网友提出了这样一个SQL挑战问题(原话不是这样,为了说明问题,我略做调整些): 问题说明如下 有一条个销售报表TEST : 商品 金额 A 1400 B 800 C 790 .

群里面有位网友提出了这样一个SQL挑战问题(原话不是这样,为了说明问题,我略做调整些):

问题说明如下

有一条个销售报表TEST :

商品 金额

A 1400

B 800

C 790

... ...

现在有这样一个需求(要写一个SQL取出如下数据):先按销售金额倒叙排序,然后从这个报表取出前N条记录,并且这N条记录的销售金额之和是总金额的80%(<= 80%), 80%将作为一个查询条件(有可能是20%,30%).他的想法是用嵌套函数 递归做法记录砍掉一半判断是否达到百分比 如果不足再取后半部分的一半 类似这样的方法;还有就是逐行金额相加当金额到达80%的时候 记录就从头显示到该条的前一条。 现在他想有没有其他跟高效的方法来实现这个需求?

那么我看到这个问题的时候,觉得有嵌套函数递归处理的方法的效率肯定是最低的,毕竟SQL不擅长于做逻辑处理。那么有没有更好的方法来实现呢?大家在看后面方法的时候,可以思考一下有没有更好的方法,能够达到一击必杀的效果(一个SQL搞定)。欢迎大家探讨!

下面是我的一个解决思路和方法,我在按销售金额倒叙排列的时候,能否得到一个销售金额的累加值?然后把这个累加值除以销售总金额即得到累加金额占总金额的一个比例,然后我们再加上查询条件。即可解决问题。

新建一个测试表TEST

CREATE TABLE TEST
(   
    PRODUCT_NAME CHAR(32), --商品名称   
    SALE_AMOUNT FLOAT    --销售金额 
)
 

插入测试数据

Code Snippet
  1. INSERT INTO TEST
  2.  
  3. SELECT 'A' ,13000 UNION ALL
  4.  
  5. SELECT 'A' ,12000 UNION ALL
  6.  
  7. SELECT 'A' ,9000 UNION ALL
  8.  
  9. SELECT 'B' ,167000 UNION ALL
  10.  
  11. SELECT 'B' ,137000 UNION ALL
  12.  
  13. SELECT 'B' ,107000 UNION ALL
  14.  
  15. SELECT 'C' ,78000 UNION ALL
  16.  
  17. SELECT 'C' ,12000;

实现销售金额的累加值字段的脚本(这个脚本效率没有测试,小量数据应该没有问题)

Code Snippet
  1. SELECT ROW_NUMBER() OVER (ORDER BY SALE_AMOUNT DESC ) AS ROW,PRODUCT_NAME,
  2.        T.SALE_AMOUNT,
  3.          (SELECT SUM(SALE_AMOUNT)AS ACCUMATE_SALE FROM TEST WHERE T.SALE_AMOUNT <= SALE_AMOUNT ) AS ACCUMATE_SALE
  4. FROM TEST T

(截图)

clip_image001

那么接下来我们来实现上面的思路

SELECT  ROW_NUMBER() OVER ( ORDER BY T.SALE_AMOUNT DESC ) AS ROW ,
        T.PRODUCT_NAME ,
        T.SALE_AMOUNT ,
        ( SELECT    SUM(SALE_AMOUNT) SUM_SALE
          FROM      TEST
          WHERE     T.SALE_AMOUNT <= SALE_AMOUNT
        ) / L.SALE_AMOUNT AS SUM_RAT
FROM    TEST T ,
        ( SELECT    SUM(SALE_AMOUNT) AS SALE_AMOUNT
          FROM      TEST
        ) L

                                     截图

clip_image002

接下来就水到渠成了

SELECT T.ROW, T.PRODUCT_NAME, T.SALE_AMOUNT, T.SUM_RAT FROM 
(
SELECT ROW_NUMBER() OVER(ORDER BY T.SALE_AMOUNT DESC) AS ROW,
       T.PRODUCT_NAME,
       T.SALE_AMOUNT,
       (SELECT SUM(SALE_AMOUNT) SUM_SALE
          FROM TEST
         WHERE T.SALE_AMOUNT <= SALE_AMOUNT) / L.SALE_AMOUNT AS SUM_RAT
  FROM TEST T, (SELECT SUM(SALE_AMOUNT) AS SALE_AMOUNT FROM TEST) L
) T WHERE SUM_RAT < 0.8

截图

clip_image003

后记总结:其实我们可以用SQL很巧妙的实现很多逻辑复杂的需求,避免我们去做大量复杂的逻辑处理,这就需求我们开动脑筋,挑战极限。像ITPUT就有很多SQL挑战问题http://www.itpub.net/forum.php?mod=forumdisplay&fid=3&filter=typeid&typeid=1808 ,国外网站例如http://www.plsqlchallenge.com/, 有兴趣的同学尽可去尝试一下。

相关文章
|
7月前
|
SQL Oracle 关系型数据库
选择适合您网站的 SQL 托管:MS SQL Server、Oracle、MySQL 和 MS Ac
如果您希望您的网站能够存储和检索数据,您的Web服务器应该能够访问使用SQL语言的数据库系统。以下是一些常见的SQL托管选项:
87 1
|
7月前
|
SQL Oracle 关系型数据库
选择适合您网站的 SQL 托管:MS SQL Server、Oracle、MySQL
如果您希望您的网站能够存储和检索数据,您的Web服务器应该能够访问使用SQL语言的数据库系统。以下是一些常见的SQL托管选项:
93 2
|
SQL 网络协议 Ubuntu
Docker安装MS SQL Server并使用Navicat远程连接
Docker安装MS SQL Server并使用Navicat远程连接
250 0
|
SQL Web App开发 关系型数据库
PostgreSQL 与 MS SQL(SQL Server) 类型映射关系
标签 PostgreSQL , ms sql , SQL Server , 类型映射 背景 PostgreSQL与SQL Server的类型映射: 1、常用类型映射 https://www.codeproject.
1467 0
查看MS SQL最耗时间资源的SQL
查看MS SQL最耗时间资源的SQL
109 0
MS SQL 锁与事务
MS SQL 锁与事务加锁的主要目的是为了防止并发操作时导致的数据不一致等问题,锁分为共享锁(S)、更新锁(U)、排他锁(X),共享锁与更新只是单向兼容?传说中的单相思? 事务 事务能保证数据操作的原子性,要么内部操作都提交,要么都回退。
1004 1
|
SQL 程序员 数据库
30分钟学习MS SQL Server的事务与并发
本篇介绍了事务和并发,重点解释了事务是个什么鬼,以及在SQL Server中如何管理事务。演示了在SQL Server中如何把一个事务访问的数据和其他事务的不一致性使用进行隔离,以及如何处理死锁的情况。
1138 0
|
SQL 数据库 Go
作业配置规范文档[MS SQL]
原文:作业配置规范文档[MS SQL] 作业配置规范文档(MS SQL)     文档类型 MS SQL数据库作业配置规范文档 创建日期 2015-07-30 版本变化 V3.
853 0
|
SQL 监控 Go
MS SQL 监控错误日志的告警信息
原文:MS SQL 监控错误日志的告警信息     SQL Server的错误消息(Error Message)按照消息的严重级别一共划分25个等级,级别越高,表示严重性也越高。但是如果你统计sys.messages,你会发现,实际上只有16(SQL SERVER 2008/2012)或17个(SQL SERVER 2005)个级别。
767 0
|
SQL Go 数据库
MS SQL 统计信息浅析上篇
原文:MS SQL 统计信息浅析上篇 统计信息概念     统计信息是一些对象,这些对象包含在表或索引视图中一列或多列中的数据分布有关的统计信息。数据库查询优化器使用这些统计信息来估计查询结果中的基数或行数。
808 0