不固定表名的多表联合查询 请大家帮忙 分不是问题

minghan0314 2011-05-10 05:10:46
工作快两年了 四月份刚换的工作 家里附近的一个大型卖场 已经不涉及到具体的编程工作了 就是维护一下数据库 领导有或者有些部门偶尔需要一些小程序 也能搞定

最近接触一个比较头疼的任务 因为之前的工作没有涉及过多的sql问题 所以现在碰见了感觉基础知识太差

问题是这样的:现在每个月都有一个销售明细表 表里有时间等明细字段 当前月的表名为TABLE_J 之前的每个月的表名为TABLE_J201105 TABLE_JYYYYMM这样的格式 表的字段都是一样的 这个卖场用的软件里有自定义报表的功能 能够自己添加sql语句 而且有能写预处理sql语句的地方

现在的需求是要求能够查出自定义月的数据 比如我时间选择4月3号-5月8号的数据 就要联合TABLE_J表和TABLE_J201104这两个表 要是查询1月3号-3月9号的数据 就要联合TABLE_J201101 TABLE_J201102 TABLE_J201103这三个表

有什么方法能在预处理sql语句的地方写出需要的存储或者语句 然后在查询的时候用一条语句就能把所查时间范围内的所有表的数据查询出来呢?

请各位不吝赐教 谢谢

...全文
240 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
fancy0109 2011-05-12
  • 打赏
  • 举报
回复
这个写个存储过程好像不是太复杂:
建立对时间段起始日期(YYYYMM模式)缓存变量;
1、你的表名,TABLE_JYYYYMM的模式时间已经有了:
select [name] tableName
from sysobjects
where right(name, 6) between @StartDate and @EndDate
建议建立一个对TABLE_JYYYYMM管理的表,如:tbList,这样就可以用tbList代替sysobjects;
2、有了确定的表名(数据库中一定要存在,通过1基本保证了这点),就可以拼接sql语句了,union all就可以了;
3、准备好了在指定时间(单位:月,因为:YYYYMM模式)的数据集,就可以在这个数据集上过滤到具体日的数据了
minghan0314 2011-05-12
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 herowang 的回复:]

感觉你的问题出在怎么知道使用了哪些表,这个可以通过对你输入的日期范围进行分析,生成时间范围内的月份,然后加上table_J+生成的月份即可
[/Quote]
是的 如果通过代码(VB.NET C++)来实现我可以写出来 但是如果只通过存储和sql语句就不太明白了

自己sql基础比较差 只对sql标准语句熟悉点 但是存储过程就不明白了 还有sqlserver其中的T-SQL之前也是没有过多了解 正在充电中....
  • 打赏
  • 举报
回复
感觉你的问题出在怎么知道使用了哪些表,这个可以通过对你输入的日期范围进行分析,生成时间范围内的月份,然后加上table_J+生成的月份即可
minghan0314 2011-05-12
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 so_cool 的回复:]
SQL code
create table TABLE_J201104
(
id int,
name varchar(20),
dt datetime,
qty int
)
Create table TABLE_J201105
(
id int,
name varchar(20),
dt datetime,
……
[/Quote]

非常感谢这位朋友的详细的讲解 学习了
So_CooL 2011-05-11
  • 打赏
  • 举报
回复
create table TABLE_J201104
(
id int,
name varchar(20),
dt datetime,
qty int
)
Create table TABLE_J201105
(
id int,
name varchar(20),
dt datetime,
qty int
)
Create table TABLE_J201106
(
id int,
name varchar(20),
dt datetime,
qty int
)
Create table TABLE_J201107
(
id int,
name varchar(20),
dt datetime,
qty int
)
Go


Create procedure P_UserRecord
(
@beginDt datetime,
@endDt datetime
)
As
Begin
declare @i int
set @i = 1
declare @sql varchar(max)
declare @dtName varchar(30)
set @dtName ='TABLE_J'+CONVERT(varchar(6),@beginDt,112)
set @sql = 'select * from '+@dtName+' A'
while @i < datediff(month,@beginDt,@endDt)
begin
set @dtName = 'TABLE_J'+''+CONVERT(varchar(6),dateadd(month,@i,@beginDt),112)+''
set @sql = @sql + ' left join '+@dtName+' on A.name = '+@dtName+'.name'
set @i = @i + 1
End
exec(@sql)
end

--P_UserRecord '2011-04-01','2011-07-07'

id name dt qty id name dt qty id name dt qty
----------- -------------------- ----------------------- ----------- ----------- -------------------- ----------------------- ----------- ----------- -------------------- ----------------------- -----------

(0 行受影响)
So_CooL 2011-05-11
  • 打赏
  • 举报
回复
可以的 贴出表结构出来.
minghan0314 2011-05-10
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 dawugui 的回复:]

引用 5 楼 minghan0314 的回复:
感谢这位朋友的资料 我还有个问题 就是多表联合查询的时候 表的数量不固定 但是表命名规则都一样 怎么控制?

如果真能做到这么智能就好了,帮顶.
[/Quote]
这个....可能是我没说清楚 当前月的表名为TABLE_J 其他月的表名为TABLE_J201104这样的TABLE_J+YYYY+MM的格式 这些表的字段都是相同的 并且都有时间字段 现在想根据提供的两个时间参数来查询表的数据 这就遇到了表的个数不固定的查询问题 1-3月是三个表 1-5月是5个表 其中还有一个TABLE_J表...
dawugui 2011-05-10
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 minghan0314 的回复:]
感谢这位朋友的资料 我还有个问题 就是多表联合查询的时候 表的数量不固定 但是表命名规则都一样 怎么控制?[/Quote]

如果真能做到这么智能就好了,帮顶.
minghan0314 2011-05-10
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 dawugui 的回复:]

不固定表名的话,需要使用动态SQL.
参考如下的:

--动态sql语句基本语法
SQL code

1 :普通SQL语句可以用Exec执行

eg: Select * from tableName
Exec('select * from tableName')
Exec sp_executesql N'select * from tableName' -- 请注意字符串前一定……
[/Quote]
感谢这位朋友的资料 我还有个问题 就是多表联合查询的时候 表的数量不固定 但是表命名规则都一样 怎么控制?
minghan0314 2011-05-10
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 xuexiaodong2009 的回复:]

在数据库中拼sql语句,类似
declare @sql as nvarchar(max)
set @sql=''
select @sql=@sql+',max(case FID when '+ltrim(FID)+' then FID else 0 end) as FID'+ltrim(FID)
+',max(case FID when '+ltrim(F……
[/Quote]
如果我要穿进去两个时间参数 应该在哪里加入 执行的时候要如何操作呢?如何控制它选择动态的表名和表的数量?

期待您的指点
xuexiaodong2009 2011-05-10
  • 打赏
  • 举报
回复
在数据库中拼sql语句,类似
declare @sql as nvarchar(max)
set @sql=''
select @sql=@sql+',max(case FID when '+ltrim(FID)+' then FID else 0 end) as FID'+ltrim(FID)
+',max(case FID when '+ltrim(FID)+' then FName else '''' end) as FName'+ltrim(FID)
from #tb1
set @sql='select t2.*,t1.* from #tb2 as t2 left join '+'(select '+stuff(@sql,1,1,'')+' from #tb1 )'+' as t1 on 1=1'
exec(@sql)
xuexiaodong2009 2011-05-10
  • 打赏
  • 举报
回复
在数据库中拼sql语句

27,579

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 应用实例
社区管理员
  • 应用实例社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧