在sql server中动态获取来自不同数据库的数据

时间:2011-06-01 11:38:35

标签: sql-server

我在sql查询中遇到问题。我的数据库在每个表中都有相同的表和相同的列。我想从每个数据库中的两个或三个表中检索相同的列。 离。

DatebaseName      TableName(exist in every database)

Demo Patient, charge, WorkDescriptor Medical Patient, charge, WorkDescriptor Test Patient, charge, WorkDescriptor

这是我的查询


select 
db_name() as DBName,
substring(convert(varchar, c.eDate, 101), 0, 11) as Date,
c.operatorID as username,
count(wd.code) as TotalCPT,
p.acctnumber as TotalPatient,
sum(c.amount) as TotalAmount
from Charge c
inner join workDescriptor wd on wd.IDWorkDescriptor = c.WorkDescriptorID
inner join patient p on c.PatientID = p.IDPatient
where c.eDate between '01/01/2009' and '05/31/2011'
group by c.operatorID, substring(convert(varchar, c.eDate, 101), 0, 11), p.acctnumber
order by substring(convert(varchar, c.eDate, 101), 0, 11)
compute sum(count(wd.code))

它正在检索当前数据库的数据。但 我想要来自每个数据库的输出数据。 喜欢 示例解决方案

DBName      Date(mm/dd/yyyy)Username  TotalCPT  TotalPatient TotalAmount
Demo           01/01/2010      A         1           1            41.82
Demo           01/01/2010      A         5           4            70.00
Demo           01/01/2010      B         3           3            41.84
Medical        01/02/2010      A         1           1             0.00
Medical        01/02/2010      B         5           4            50.24
Medical        01/02/2010      B         3           3            21.50    
Test           01/03/2010      A         1           1            56.98         
Test           01/03/2010      A         5           4            45.75         
Test           01/03/2010      B         3           3            56.52    
                                       ------     --------       ---------------
                                        27           25          384.65

任何建议将不胜感激。如果您有任何查询来实现我的目标。 提前致谢

2 个答案:

答案 0 :(得分:0)

非常简单,使用联合,3部分命名,并对数据库名称进行硬编码;像这样:

select 
'Demo' as DBName,
substring(convert(varchar, c.eDate, 101), 0, 11) as Date,
c.operatorID as username,
count(wd.code) as TotalCPT,
p.acctnumber as TotalPatient,
sum(c.amount) as TotalAmount
from Demo.dbo.Charge c
inner join Demo.dbo.workDescriptor wd on wd.IDWorkDescriptor = c.WorkDescriptorID
inner join Demo.dbo.patient p on c.PatientID = p.IDPatient
where c.eDate between '01/01/2009' and '05/31/2011'
group by c.operatorID, substring(convert(varchar, c.eDate, 101), 0, 11), p.acctnumber
order by substring(convert(varchar, c.eDate, 101), 0, 11)
compute sum(count(wd.code))
UNION ALL
select 
'Medical' as DBName,
substring(convert(varchar, c.eDate, 101), 0, 11) as Date,
c.operatorID as username,
count(wd.code) as TotalCPT,
p.acctnumber as TotalPatient,
sum(c.amount) as TotalAmount
from Medical.dbo.Charge c
inner join Medical.dbo.workDescriptor wd on wd.IDWorkDescriptor = c.WorkDescriptorID
inner join Medical.dbo.patient p on c.PatientID = p.IDPatient
where c.eDate between '01/01/2009' and '05/31/2011'
group by c.operatorID, substring(convert(varchar, c.eDate, 101), 0, 11), p.acctnumber
order by substring(convert(varchar, c.eDate, 101), 0, 11)
compute sum(count(wd.code))
UNION ALL
select 
'Test' as DBName,
substring(convert(varchar, c.eDate, 101), 0, 11) as Date,
c.operatorID as username,
count(wd.code) as TotalCPT,
p.acctnumber as TotalPatient,
sum(c.amount) as TotalAmount
from Test.dbo.Charge c
inner join Test.dbo.workDescriptor wd on wd.IDWorkDescriptor = c.WorkDescriptorID
inner join Test.dbo.patient p on c.PatientID = p.IDPatient
where c.eDate between '01/01/2009' and '05/31/2011'
group by c.operatorID, substring(convert(varchar, c.eDate, 101), 0, 11), p.acctnumber
order by substring(convert(varchar, c.eDate, 101), 0, 11)
compute sum(count(wd.code))

还有其他方法可以做到这一点,但是这个方法可行,并且与我现在能想到的其他方法一样有效。

基于评论的更新

好的,这应该有用,可能需要一些调整,但想法就在那里:

CREATE TABLE #t1 (DBName VARCHAR(128), [Date] DATETIME, username VARCHAR(128), TotalCPT INT, TotalPatient INT, TotalAmount DECIMAL (16,2))


DECLARE @dbName VARCHAR(128), @sql VARCHAR(MAX), @fromDate DATETIME, @toDate DATETIME

SELECT @fromDate = '01/01/2009', @toDate = '05/31/2011'

DECLARE db_cursor CURSOR FOR 

SELECT name
FROM Master.sys.databases
WHERE name NOT IN ('master','tempdb','msdb','model')

OPEN db_cursor

FETCH NEXT FROM db_cursor INTO @dbName

WHILE @@FETCH_STATUS = 0
BEGIN

SELECT @sql = '
INSERT INTO #t1(DBName, [Date], username, TotalCPT, TotalPatient, TotalAmount)
select ''' + @dbName + ''' as DBName,
substring(convert(varchar, c.eDate, 101), 0, 11) as Date,
c.operatorID as username,
count(wd.code) as TotalCPT,
p.acctnumber as TotalPatient,
sum(c.amount) as TotalAmount
from Demo.dbo.Charge c
inner join Demo.dbo.workDescriptor wd on wd.IDWorkDescriptor = c.WorkDescriptorID
inner join Demo.dbo.patient p on c.PatientID = p.IDPatient
where c.eDate between ''' + @fromDate + ''' and ''' + @toDate + '''
group by c.operatorID, substring(convert(varchar, c.eDate, 101), 0, 11), p.acctnumber
order by substring(convert(varchar, c.eDate, 101), 0, 11)
compute sum(count(wd.code))'

EXEC (@sql)

FETCH NEXT FROM db_cursor INTO @dbName

END
CLOSE db_cursor
DEALLOCATE db_cursor


SELECT * FROM #t1

DROP TABLE #t1

答案 1 :(得分:0)

如果对每个数据库运行绝对相同的查询,你可以尝试这样的事情:

DECLARE @DBIndex int;

DECLARE @results TABLE (  -- the types are based on assumptions, should be reviewed
  DBName sysname,
  Date varchar(11),
  username varchar(50),
  TotalCPT int,
  TotalPatient int,
  TotalAmount decimal(10, 2)
);

SET @DBIndex = 0;

WHILE @DBIndex < 3 BEGIN
  SET @DBIndex = @DBIndex + 1;
  IF @DBIndex = 1
    USE Demo
  ELSE IF @DBIndex = 2
    USE Medical
  ELSE IF @DBIndex = 3
    USE Test;

  INSERT INTO @results
  select 
  db_name() as DBName,
  substring(convert(varchar, c.eDate, 101), 0, 11) as Date,
  c.operatorID as username,
  count(wd.code) as TotalCPT,
  p.acctnumber as TotalPatient,
  sum(c.amount) as TotalAmount
  from Charge c
  inner join workDescriptor wd on wd.IDWorkDescriptor = c.WorkDescriptorID
  inner join patient p on c.PatientID = p.IDPatient
  where c.eDate between '01/01/2009' and '05/31/2011'
  group by c.operatorID, substring(convert(varchar, c.eDate, 101), 0, 11), p.acctnumber
  order by substring(convert(varchar, c.eDate, 101), 0, 11)
  compute sum(count(wd.code))
END;

SELECT *
FROM @results
ORDER BY …

我可能会从主查询中删除ORDER BY子句,因为最终重要的是最终SELECT中的ORDER BY,即来自@results。然后可能需要将一些其他列添加到@results,以便在ORDER BY中使用它们。

相关问题