能不能好好的过年,就看这一次了,结了所有的帖,重新求高手出招
/* **********
问题1
********** */
表:duizhao
--------------------------------------
id zyid zyname gsid gsnames
1 001 aaa 100 aaab
2 001 aaa 101 aaac
3 001 aaa 102 aaad
4 002 bbb 103 bbbc
5 002 bbb 104 bbbf
6 003 ccc 105 cccs
7 004 ddd 106 dddf
8 005 eee 107 eees
9 006 fff 108 fffs
10 006 ggg 109 ggsd
表:t_login
--------------------------------------
id gsid 公司名称 用户名 查询范围
21 100 aaab alibaba 100,103,106,107,109
表:shenp (与v_shenp表结构相同)
公司id 公司名称 用户名 申请时间 批复日期 申请金额 批复金额
--------------------------------------
100 aaab alibaba 2007-01-07 2007-01-08 500 400
101 aaab asrock 2007-01-07 2007-02-08 400 300
102 aaad ds 2007-01-05 2007-03-05 600 550
表:v_shenp
gsid 公司名称 用户名 申请时间 批复日期 申请金额 批复金额
--------------------------------------
100 aaab alibaba 2007-08-07 2007-08-08 500 400
101 aaab asrock 2007-09-07 2007-09-08 400 300
102 aaad ds 2007-10-05 2007-10-05 600 550
问题1:表duizhoa 表示大类公司与相应的公司名称对应关系,比如:
gsid为100,101,102的公司都属于zyid为001的公司,现在的需求是,用户alibaba有一个查询权限,他可
以查询对应的gsid为100,103,106,107,109的公司信息,现在有另外一个
需求需要实际上实现如下的功能,用户alibaba对应的查询范围是100,103,106,107,109 --我需要根据
这几个gsid查询出他所对应的zyid,那么可以查询出的用户alibaba对应的zyid分别是:001,002,004,005,006
然后呢,根据这几个对应的zyid查出他们所对应的所有gsid,也就是结果:100,101,102,103,104,106,107,108,109
。
问题2:shenp与v_shenp表的表结构相同,分别为上半年数据和下半年数据,现在需要一个存储过程实现:按照公司(也就是gsid)
进行分组求合的数据报表,得出每一个公司按输入日期或是全年的统计数据,这个存储过程有三个参数,一个是@companyname,输入
参数的形式是如215,125,455之类,或是为null 或是为0,为NULL或是为0,则查询全部公司的“批复金额”的汇总数据,如果
为具体的数组,则会按照问题1的需求逻辑将输入的数组进行处理,将得出的公司的数据按gsid进行分组,
@startdate指开始时间(指的是“批复日期”字段) @enddate是结束时间,也就是用户可以指定一个时间段进行查询全部或是某一个
或是某几个公司的“批复金额”汇总数据,需要特别指出的是这三个参数都有为空或不为空的时侯。
其实呢,现在的存储过程已经基本实现了所有的功能,只是在当输入的@companyname为215,125,455这种形式的数组时会报错,我想应该是
存储过程中实现gsid来回反查的部份的表示方法有问题,但这样解释来解释去也没有让大家明白,所以只好重新整理,还只怕大家看了
会更晕。下面是供参考的存储过程,大家参考一下,应该会明白我说的具体意思什么.
--------------------------------------
CREATE proc zjreport_release
(
@companyname varchar(1000)=null,
@startdate datetime=null,
@enddate datetime=null
)
as
begin
select 公司名称zy as 公司名称,sum(申请用款总额) as 借款额 from
(
select 公司id,公司名称,sum(批复金额) as 申请用款总额
from
(
select * from v_shenp
union all
select * from shenp
) tt1
where 审批意见= '同意 '
/* ----大家注意其实这个存储过程出问题的部份就这个加注释的中间的部份,而且case when @companyname is null or @companyname = 0 then gsid这一部份也是正常的,不正常的是else以后的--- */
and
gsid in (
case when @companyname is null or @companyname = 0 then gsid else
(select gsid from duizhao as tmp
where exists
(
select * from duizhao as tmpA
where exists
(
select 1 from t_login
where charindex( ', '+rtrim(tmpA.gsid)+ ', ', ', '+@companyname+ ', ')> 0
) and tmpA.zyid = tmp.zyid ))
end )
/* ------------------------ */
and 请求时间> (case when @startdate is null then 请求时间-1 else @startdate end)
and 请求时间 <(case when @enddate is null then 请求时间+1 else @enddate end)
group by 公司id,公司名称
)tt ,duizhao aa where tt.公司id = aa.gsid group by 公司名称zy
end
GO
如老大们有什么好的写法更好,或是能把我的这段错误部份改好,也行,但要声明一下,我上面的存储过程在查询分析器中分析没有语法错误!
/* **********
问题2
********** */
在我的SQL服务器上,有N多数据库实体,所有的数据库实体表结构完全相同,每一个数据库实体中都有一个t_itemclass表,每一个t_itemclass表中都有一个t_itemclassid为4的记录,
======
参考1:
======
select DISTINCT FFrameWorkID ,cdbname,cacc_name,FDatabaseLocation
from master.dbo.aaa
join
bbb.dbo.t_GR_FrameWork
on master.dbo.aaa.cacc_name= bbbdbo.t_GR_FrameWork.FK3DataSourceName
利用上面的语句我可以得到所有数据库实体的相关信息
:
上面的语句执行出来的结果如下样式:
FFrameWorkID cdbname cacc_name FDatabaseLocation
1 20050616112908ccc 003.001 ab
2 20070124000800ccc 003.002 ab
3 20070109093209dddd 001.001.001 abc
现在的需求是:
我在想上面的结果后面加上一行值,这列值是由如下语句得出:
select faa from '+cdbname+ '.dbo.t_itemclass where t_itemclassid=4 --大家注意这里的 '+cdbname+ ' 就是指上面的“参考1”处查出的cdbname值,需要动态的,而得到的结果样式应如下:
---------------------
FFrameWorkID cdbname cacc_name FDatabaseLocation faa
1 20050616112908ccc 003.001 ab 2
2 20070124000800ccc 003.002 ab 1
3 20070109093209dddd 001.001.001 abc 3
不知道,这个需求要如何实现,不管用什么方法,动态语句,直接的查询,存储过程,都可以,高手出招吧!
[解决办法]
1. try
declare @user varchar(100)
set @user= 'alibaba '
select gsid from duizhao
where zyid in (select zyid from duizhao a
inner join t_login b
on charindex( ', '+a.gsid+ ', ' , ', '+b.[查询范围]+ ', ' )> 0
and b.[用户名]=@user
)
[解决办法]
2. try
declare @company varchar(200),@start datetime,@end datetime
select T1.公司名称, sum(T2. 批复金额) as [借款额]
from (select * from shenp
union all
select * from v_shenp
) T1
inner join
(select A.gsid ,sum(A.批复金额) as 批复金额
from
(select * from shenp
union all
select * from v_shenp
) A
where (charindex( ', '+rtrim(A.gsid)+ ', ' , ', '+@company+ ', ')> 0 or isnull(@company, ' ')= '0 ')
and A.批复日期 > =isnull(@start, '1900-01-01 ')
and A.批复日期 <=isnull(@end, '2999-01-01 ')
and A.审批意见= '同意 '
group by A.gsid) T2
on T1.gsid=T2.gsid
group by T1.公司名称
[解决办法]
--沒有測試,隨手寫的可能有誤,
--1. try
declare @user varchar(100)
set @user= 'alibaba '
select gsid from duizhao
where zyid in (select zyid from duizhao a
inner join t_login b
on charindex( ', '+rtrim(a.gsid)+ ', ' , ', '+b.[查询范围]+ ', ' )> 0
and b.[用户名]=@user
)
--2.try
declare @company varchar(200),@start datetime,@end datetime
select T1.公司名称, sum(T2. 批复金额) as [借款额]
from (select * from shenp
union all
select * from v_shenp
) T1
inner join
(select A.gsid ,sum(A.批复金额) as 批复金额
from
(select * from shenp
union all
select * from v_shenp
) A
where (charindex( ', '+rtrim(A.gsid)+ ', ' , ', '+@company+ ', ')> 0 or isnull(@company, ' ')= '0 ')
and A.批复日期 > =isnull(@start, '1900-01-01 ')
and A.批复日期 <=isnull(@end, '2999-01-01 ')
and A.审批意见= '同意 '
group by A.gsid) T2
on T1.gsid=T2.gsid
group by T1.公司名称
[解决办法]
问题二:
我觉得使用存储过程结合游标可以实现,可能效率比较低的
我没有测试过,自己去试试吧
create proc T
as
begin
DECLARE @cdbname varchar(15),@fa int
declare @t table (FFrameWorkID int ,cdbname varchar(100),cacc_name varchar(50),FDatabaseLocation varchar(10),fa int)
insert into @t FFrameWorkID ,cdbname,cacc_name,FDatabaseLocation
select DISTINCT FFrameWorkID ,cdbname,cacc_name,FDatabaseLocation
from master.dbo.aaa
join bbb.dbo.t_GR_FrameWork
on master.dbo.aaa.cacc_name= bbbdbo.t_GR_FrameWork.FK3DataSourceName
DECLARE ak47_cursor CURSOR FOR
select cdbname
from @t
OPEN ak47_cursor
FETCH NEXT FROM ak47_cursor
INTO @cdbname
WHILE @@FETCH_STATUS = 0
BEGIN
sp_executesql 'select @fa = fa from '+@cdbname+ '.dbo.t_itemclass where t_itemclassid=4 ',N '@fa int output ',@fa output
update a set fa = @fa
from @t a
where cdbname =@cdbname
FETCH NEXT FROM ak47_cursor
INTO @cdbname
END
CLOSE ak47_cursor
DEALLOCATE ak47_cursor
select * from @t
end