Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1258715
  • 博文数量: 510
  • 博客积分: 20296
  • 博客等级: 上将
  • 技术积分: 4680
  • 用 户 组: 普通用户
  • 注册时间: 2007-10-30 03:58
文章存档

2011年(13)

2010年(92)

2009年(242)

2008年(163)

我的朋友

分类: 数据库开发技术

2010-09-16 19:35:25

      在前一段时间中遇到一个需求..统计某一种商品在某一天中的销售数量,当天没有销售的时候,数量显示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

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

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

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

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

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

SELECT a.day , isnull(BidsCombo_Price,0) as
BidsCombo_Price, isnull( BidsTrade_Count,0) as
BidsTrade_CountFROM (
SELECT year(Date) as year,month(Date) as month,day(Date) as [day]
FROM dbo.CN80s_DDPM_FN_GETDATE(@beginTime,@endTime,NULL) ) a
LEFT JOIN
DDPM_V_BidsTradeRecount b
 ON a.day = b.day
AND a.year=b.year
AND a.month=b.month

GO


阅读(847) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~