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

关于一个sqlserver复杂的查询

2013-03-06 
关于一个sqlserver复杂的查询,求助本帖最后由 J2EE_ME 于 2013-02-15 14:20:34 编辑各位高人,求解决方案,

关于一个sqlserver复杂的查询,求助
本帖最后由 J2EE_ME 于 2013-02-15 14:20:34 编辑 各位高人,求解决方案, 我目前有4个表,一个是主表,3个是副表。
我现在需要一个查询来拿到所有表中的数据。
暂且给这4个表命名为,company, history, staff,task. 每个公司对应多个history,staff和task
首先,我必须要用
select * from company where status = 'active'来查询所有company信息,当然了,也包括了companyID。
然后我要用
select * from history where company_id = 'companyID'
select * from staff where company_id = 'companyID'
select * from task where company_id = 'companyID'

company的表有上万个记录,副表里的更多,我发现旧的查询方法是查出companyID,然后java用for 循环去查询副表,效率太低下,如果有1000个公司,就要连接3000次数据库去查询副表。等10分钟还没出来。
由于当初设计的时候,没用用hibernate的一对多,所以没法用hibernate一下子搞定,只有写一个强大的查询才行了,各位高人,拜托了。求解决方案。
是用存储过程还是如何呢?
[解决办法]
SQL存储过程内容大致如下:
select * from
Company
inner join history on history.company_id = Company.companyID
inner join staff on staff.company_id = Company.companyID
inner join task on task.company_id = Company.companyID
where company.status = 'active'

但是不知道你返回的数据条数有多少,如果上千可以讲究,但是如果上万,那么在程序设计中还是需要避免的,因为太多的数据基本用书也不会全部看,一般就只关心自己感兴趣的。这种情况下,那你可以使用原先的:select * from company where status = 'active'先建立一个下拉菜单,当用户选择了一个company以后,再选择出这个company的信息
[解决办法]
你的“需要一个查询来拿到所有表中的数据”太抽象了,很难给出答案,最好给少量数据,和期待结果,如果你是为了页面展示,用sql来搞成树状结构也不好弄。数据量不大且不是频繁使用的话可以考虑控件来多次查询,如果频繁使用,可以考虑页面缓存所有数据,但是你首先要清晰地告诉别人你要干嘛
[解决办法]

用 select * from company a 
outer cross apply
(select top(1)* from history b where a.company_id = b.company_id)b
(select top(1)* from staff b where a.company_id = b.company_id)c
(select top(1)* from task b where a.company_id = b.company_id)d
where a.status = 'active'

[解决办法]
用户就是想要一次下载全部内容到他们的客户端,然后他们慢慢看。。。如果这个客户1个月不更新,数据量是相当的大。。。

数据可能每天都会有更新。客户端去更新的时候可能数据量很大。。。。

=============

说白了你这个就是客户端下载所有服务器数据到本地做离线查看。
这种功能其实可以在后台开线程做的,时间长就给一个进度条好了。
[解决办法]
引用:
引用:
SQL存储过程内容大致如下:
select * from
Company
inner join history on history.company_id = Company.companyID
inner join staff on staff.company_id = Company.companyID
inner join task ……


那就把程序弄成多线程,头1000个直接返回浏览,之后的再慢慢读。
或者你每天直接把数据先处理完存在一个表格中,或者存成csv,excel啥的让程序再度。
[解决办法]
引用:
引用:用户就是想要一次下载全部内容到他们的客户端,然后他们慢慢看。。。如果这个客户1个月不更新,数据量是相当的大。。。

数据可能每天都会有更新。客户端去更新的时候可能数据量很大。。。。

=============

说白了你这个就是客户端下载所有服务器数据到本地做离线查看。
这种功能其实可以在后台开线程做的,时间长就给一个……


--比如你在服务器端的数据库,表里面加一个表示时间的位,比如叫LastUpdateTime(当然为了性能考虑你可能需要用int/bigint再加索引,用1900-01-01到现在的总天数估计就ok了)。

--服务器提供一个方法GetDataByTimeStamp(bigint lastUpdateTime),可以返回所有LastUpdateTime >= lastUpdateTime的数据,最好再加一个返回的这批数据中的Max(LastUpdateTime)。



--服务器提供一个方法GetDataByCompanyId(string[] ids),可以返回给定CompanyId列表的数据。

--客户端建立相同的结构(无所谓,看你怎么存取方便),同样建立一个LastUpdateTime位,但这个位不是从服务器端来的,而是你每次更新本地数据的时候更新成当前时间。

--客户端设置一个LastSyncTime,初始化时候是0就好了。

--每次启动客户端的时候,后台开一个线程调用GetDataByTimeStamp(LastSyncTime),(第一次就是0了,全更新),把数据更新到本地,记得更新本地每个记录的LastUpdateTime。成功后再用一起返回的那个Max(LastUpdateTime)更新本机的LastSyncTime设置。

--当用户查看一组数据时,先查询本机上这组数据的LastUpdateTime(没有的设成0或是什么的),如果这批数据里面有更新时间比较早的(比如10天以前更新的),就先调用GetDataByCompanyId(string[] ids)单独更新这一批用户看的数据。

*好处:
后台更新不需要阻塞用户的操作,可以在状态栏给他一个提示:“正在同步最新数据 %%...”,让他知道有这么一回事,注意下网络带宽就好了。当用户查询数据的时候,一屏幕的数据也没多少,所以就算他请求的所有id都在GetDataByCompanyId里面他也应该感觉不到太大的延时。

**需要注意的地方:
--你可能需要重新看下业务当中的“删除”逻辑。这一套带TimeStamp的设计只对数据新增/修改起作用,删除记录的操作就不行。可能需要把删除操作改成设置一个Active标志位列为0,这样的数据不显示。

--给用户详细说明一下这些后台动作,免得他们在不知情的情况下看到那么大的流量访问,还以为自己中病毒了。

--如果GetDataByCompanyId失败,可以考虑给用户一个状态栏提醒什么的,告诉他现在看到的是本地之前更新的缓存,不是最新数据,想看最新的自己在刷新什么的。

热点排行