解决SQLServer中Group无法实现的问题

在前一段时间中遇到一个需求..统计某一种商品在某一天中的销售数量,当天没有销售的时候,数量显示0.

这个不能用一般的Group来实现.所以需要变通一下,跟一个有1-31的一个集合来Group.

有2种方案.

planA:

 
 
 
 
  1. SELECT SUM(ISNULL(BidsTrade_Money, 0))   
  2. AS [MONEY], a.number   
  3. AS [DAY]FROM MASTER..spt_values a      
  4. LEFT JOIN DDPM_T_Comm_BidsTrade b          
  5. ON  a.type = 'p'             
  6.  AND month([BidsTrade_DateCreated])='5'              
  7. AND a.number = DAY(b.[BidsTrade_DateCreated])              
  8. AND YEAR([BidsTrade_DateCreated]) = '2010'              
  9. WHERE a.number BETWEEN 1 AND 31GROUP BY a.numberorder by DAY 

使用MASTER..spt_values(产生一定范围的数字的数字,这里需要产生1-31的数字.)

但是这一种方法有缺陷,每一个月不一定都是31天.并且我们配置的SQL账号不一定有权限来访问这个函数.

planB:.通过自定义函数.

自定义函数GetOrderType(比较长- -..)

 
 
 
 
  1. CREATE function [dbo].[CN80s_FN_GetOrderType](    @tabName nvarchar(2000),      
  2. @keyOrder nvarchar(255))returns nvarchar(100)asbegin    declare @OrderTable nvarchar(255)  --表名     
  3.  declare @OrderName nvarchar(255)  --字段名      
  4. declare @OrderType nvarchar(255)  --字段类型      
  5. declare @OrderPrec nvarchar(50)  --字段长度      
  6. declare @OrderDot int  --点的位置      
  7. declare @s1 nvarchar(100) -- 临时变量1      
  8. declare @s2 nvarchar(100) -- 临时变量2    --去除排序规则    
  9. set @keyorder=REPLACE(@keyorder, ' asc', '')    --求表名、字段名      
  10. set @OrderDot=CHARINDEX('.', @keyorder)      
  11. IF @OrderDot > 0          
  12. BEGIN              
  13. SET @OrderTable = SUBSTRING(@keyorder, 0, @OrderDot)              
  14. SET @OrderName = SUBSTRING(@keyorder, @OrderDot + 1, LEN(@keyorder))         
  15. END      
  16. ELSE          
  17. BEGIN              
  18. SET @OrderTable = @tabName              
  19. SET @OrderName = @keyorder          
  20. END    --去除方括号    set @s1=REPLACE(REPLACE (@OrderTable,'[',''),']','')      
  21. set @s2=REPLACE(REPLACE (@OrderName,'[',''),']','')    --求字段类型、字段长度      
  22. SELECT @OrderType=t.[name], @OrderPrec=c.prec      
  23. FROM sysobjects o       
  24. JOIN syscolumns c on o.id=c.id      
  25. JOIN systypes t on c.xusertype=t.xusertype      
  26. WHERE o.name = @s1 AND c.[name] = @s2      
  27. if @OrderType is null    begin          
  28. SET @OrderType='Sql_Variant'      
  29. end    else    begin          
  30. IF CHARINDEX('char', @OrderType) > 0             
  31. SET @OrderType = @OrderType + '(' + CAST(@OrderPrec AS nvarchar) + ')'      
  32. end    return @OrderTypeendGO 

函数2(这个更长) 

   
    
    USE
     
    [
    CN80s.DDPM
    ]
    
GO

/* ***** Object: UserDefinedFunction [dbo].[FormatDateTime] Script Date: 08/01/2010 16:28:23 ***** */
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO



CREATE function [ dbo ] . [ FormatDateTime ] ( @Date datetime , @formatStr varchar ( 20 ))
returns varchar ( 16 )
as
begin
declare @tempstr varchar ( 20 ), @index int , @retStr varchar ( 20 ), @formatLen int , @str1 varchar ( 6 ), @str2 varchar ( 6 ), @str3 varchar ( 6 ), @j int
declare @tempformat varchar ( 20 )
select @tempformat = @formatStr , @formatStr = Upper ( @formatStr ), @index =- 1 , @retstr = ''
if @formatStr = ' MM/DD/YYYY '
set @retstr = convert ( varchar ( 10 ), @date , 101 )
else if @formatstr = ' YYYY-MM-DD '
set @retstr = Convert ( char ( 10 ), @Date , 20 )
else if @formatStr = ' YYYY.MM.DD '
set @retstr = Convert ( varchar ( 10 ), @Date , 102 )
else if @formatStr = ' YYYY/MM/DD '
set @retstr = Convert ( varchar ( 10 ), @Date , 111 )
else if @formatStr = ' DD/MM/YYYY '
set @retstr = Convert ( varchar ( 10 ), @Date , 103 )
else if @formatStr = ' DD.MM.YYYY '
set @retstr = Convert ( varchar ( 10 ), @Date , 104 )
else if @formatStr = ' DD-MM-YYYY '
set @retstr = Convert ( varchar ( 10 ), @Date , 105 )
else if @formatStr = ' YYYYMMDD '
set @retstr = Convert ( varchar ( 10 ), @Date , 112 )
else
begin
select @tempformat = @formatStr , @formatLen = len ( @formatStr )
if @formatLen > 8
begin
set @index = charindex ( ' M ' , @tempformat )
select @str1 =right ( left ( @tempformat , @index - 1 ), @index - 5 ), @str2 =right ( @tempformat , @formatLen - @index - 1 )
select @index = charindex ( ' D ' , @str2 ), @str3 = @str2
set @str2 =left ( @str2 , @index - 1 )
set @str3 =right ( @str3 , len ( @str3 ) - @index - 1 )
end
select @tempstr = Convert ( char ( 10 ), @Date , 20 ), @str1 = isnull ( @str1 , '' ), @str2 = isnull ( @str2 , '' ), @str3 = isnull ( @str3 , '' ), @j = 0
while @index <> 0
begin
set @index = charindex ( ' - ' , @tempstr )
if @j = 0
select @retstr =left ( @tempstr , @index - 1 ) + @str1 , @j = @j + 1
else set @retstr = @retstr +left ( @tempstr , @index - 1 ) + @str2
select @tempstr =right ( @tempstr , len ( @tempstr ) - @index )
set @index = charindex ( ' - ' , @tempstr )
end
set @retstr = @retstr + @tempstr + @str3
end
return @retstr
end


GO

可以看看调用这个函数的结果.

 
 
 
 
  1. SELECT * FROM CN80s_DDPM_FN_GETDATE('2010-05-1','2010-05-31',null) 

参数依次为:开始时间,结束时间,显示状态(null:显示所有日期,0显示所有工作日(星期一~星期五),1:显示周末,2显示周末)

当然这个函数有其他的扩展应用请各位看官天马行空.~

实际应用,这里写了一个存储过程 

 
 
 
 
  1. SELECT a.day , isnull(BidsCombo_Price,0) as   
  2. BidsCombo_Price, isnull( BidsTrade_Count,0) as    
  3. BidsTrade_CountFROM (          
  4. SELECT year(Date) as year,month(Date) as month,day(Date) as [day] 
  5. FROM dbo.CN80s_DDPM_FN_GETDATE(@beginTime,@endTime,NULL) ) a       
  6. LEFT JOIN          
  7. DDPM_V_BidsTradeRecount b         
  8.  ON  a.day = b.day          
  9. AND a.year=b.year          
  10. AND a.month=b.month    GO 

网站名称:解决SQLServer中Group无法实现的问题
标题URL:http://www.shufengxianlan.com/qtweb/news24/429174.html

网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联