首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > SQL Server >

,复杂SQL求教

2012-02-22 
高手请进,复杂SQL求教!假定有两张表:TABLEARowCodeSQLString-----------------------1000acctBetween72110

高手请进,复杂SQL求教!
假定有两张表:
TABLE   A
RowCode                           SQLString
-----------------------
1000                                 acct   Between   72110000   and   72112999  
1100                                 acct   Between   72120000   and   72122999
1200                                 acct   Between   72130000   and   72132999
....
数据有将近200条记录,SQLString中是对应TABLE   B中的条件语句

TABLE   B
Acct                               Amt
-----------------------------------------------------
72110000                       100
72111800                       200
72111900                       300
72120000                       400
72128000                       500
72130000                       600

如何获得如下结果(不要用游标的方式):
RowCode                         Amt
---------------------------
1000                               600           (注释:100+200+300)
1100                               900           (注释:400+500)
1200                               600           (注释:600)
...

[解决办法]
如果位数定长,不变.

select rowcode , sum(amt) as amt from
(
select b.acct , b.amt , a.rowcode
from a , b
where b.acct > = substr(a.SQLString , 14 , 8) and b.acct <= right(a.SQLstring , 8)
) t
group by rowcode
[解决办法]
declare @A TABLE(RowCode int,SQLString varchar(40))
insert into @A select 1000, 'acct Between 72110000 and 72112999 '
insert into @A select 1100, 'acct Between 72120000 and 72122999 '
insert into @A select 1200, 'acct Between 72130000 and 72132999 '

declare @B TABLE(Acct int,Amt int)
insert into @B select 72110000,100
insert into @B select 72111800,200
insert into @B select 72111900,300
insert into @B select 72120000,400
insert into @B select 72128000,500
insert into @B select 72130000,600


select
a.RowCode,sum(b.Amt) as Amt
from
@A a,@B b
where
b.Acct between
(substring(SQLString,13,charindex( ' and ',SQLString)-13))
and
(stuff(SQLString,1,charindex( ' and ',SQLString)+4, ' '))
group by
a.RowCode

/*
RowCode Amt
----------- -----------
1000 600


1100 400
1200 600
*/
[解决办法]
--也可以參考下面帖子的作法

http://community.csdn.net/Expert/topic/5338/5338927.xml?temp=.2254602
[解决办法]
declare @s varchar(8000)
set @s= ' '
select @s=@s+ 'select '+cast(rowcode as varchar)+ ' As rowcode,sum(amt) as Amt from B where '+SQLstring+ ' Union all '
from A
set @s= 'select * from ( '+substring(@s,1,len(@s)-10)+ ')T '
exec(@s)
原始数据:
RowCode SQLString
-------------------------------------------
1000acct Between 72110000 and 72112999
1100acct Between 72120000 and 72122999
1200acct Between 72130000 and 72132999
Acct Amt
--------------------------
72110000100
72111800200
72111900300
72120000400
72128000500
72130000600

--执行结果:
rowcode Amt
--------------
1000600
1100400
1200600

[解决办法]
CREATE TABLE TABLE_A([RowCode] INT, [SQLString] varchar(50))
INSERT INTO TABLE_A
SELECT 1000, 'acct Between 72110000 and 72112999 '
UNION ALL SELECT 1100, 'acct Between 72120000 and 72122999 '
UNION ALL SELECT 1200, 'acct Between 72130000 and 72132999 '

CREATE TABLE TABLE_B([Acct] INT, [Amt] INT)
INSERT INTO TABLE_B
SELECT 72110000, 100
UNION ALL SELECT 72111800, 200
UNION ALL SELECT 72111900, 300
UNION ALL SELECT 72120000, 400
UNION ALL SELECT 72128000, 500
UNION ALL SELECT 72130000, 600

GO

CREATE FUNCTION f_GetSum(@where VARCHAR(50))
RETURNS INT
AS
BEGIN
DECLARE @start INT
DECLARE @end INT
DECLARE @ret INT
SET @start = CAST(SUBSTRING(@where, CHARINDEX( 'Between ', @where) + 8, CHARINDEX( 'and ', @where) - CHARINDEX( 'Between ', @where) - 9) AS INT)
SET @end = CAST(SUBSTRING(@where, CHARINDEX( 'and ', @where) + 4, LEN(@where)) AS INT)
SET @ret = 0
SELECT @ret = SUM(Amt)
FROM TABLE_B
WHERE Acct BETWEEN @start AND @end
RETURN @ret
END

GO

SELECT RowCode, dbo.f_GetSum(SQLString)
FROM TABLE_A

DROP TABLE TABLE_A, TABLE_B
DROP FUNCTION f_GetSum

[解决办法]
create table A(RowCode int, SQLString varchar(50))
insert A select 1000, 'acct Between 72110000 and 72112999 '
union all select 1100, 'acct Between 72120000 and 72122999 '
union all select 1200, 'acct Between 72130000 and 72132999 '
go
create table B(Acct varchar(20), Amt int)
insert B select '72110000 ', 100
union all select '72111800 ', 200
union all select '72111900 ', 300
union all select '72120000 ', 400
union all select '72128000 ', 500
union all select '72130000 ', 600
go

select A.RowCode, Amt=sum(B.Amt) from A
inner join B on B.Acct between substring(SQLString, 14, 8) and substring(SQLString, 27, 8)
group by A.RowCode

--result
RowCode Amt
----------- -----------
1000 600
1100 400
1200 600

(3 row(s) affected)

热点排行