有没有办法在一个查询中查询135个不同的表?

时间:2011-05-02 19:20:30

标签: sql sql-server tsql

在我们的数据库中,我们有135个表,其中有一个名为EquipmentId的列。我需要查询每个表以确定它们中的任何一个是否具有等于某个值的EquipmentId。有没有办法在一个查询中执行此操作,而不是135个单独的查询?

非常感谢。

6 个答案:

答案 0 :(得分:6)

您正在查看动态SQL以生成对所有表的查询,并且可能将结果联合起来,或者使用类似未记录的sp_MSforeachtable存储过程的内容。

sp_msforeachtable 'select * from ? where equipmentid = 5'

答案 1 :(得分:5)

您可以使用查询来构建查询:

select  'union all select * from ' + name + 
             ' where EquipmentId = 42' + char(13) + char(10) 
from     sys.tables

复制结果,剥离第一个union all,然后运行查询:)

答案 2 :(得分:1)

我会将它们转储到临时表或类似的其他内容中:

CREATE TABLE #TempTable (Equip NVARCHAR(50))
sp_msforeachtable 'INSERT INTO #TempTable (Equip) SELECT Equip FROM ?'
SELECT * FROM #TempTable
DROP TABLE #TempTable

答案 3 :(得分:1)

我假设并非数据库中的所有表都有EquipmentId列。 如果这是一个有效的假设,那么sp_msforeachtable的@whereand参数将有助于过滤表。 下面的查询将显示已指定EquipmentId的所有表名。 表名将显示为此表中具有指定的EquipmentId的行数。

declare @EquipmentId int = 666

create table #Result (TableName sysname)

declare @command nvarchar(4000) = 
    'insert into #Result select ''?'' from ? where EquipmentId = ' + cast(@EquipmentId as varchar)

execute sp_msforeachtable
    @command1 = @command,
    @whereand = 'and o.id in (select object_id from sys.columns where name = ''EquipmentId'')'

select * 
from #Result 

drop table #Result 

答案 4 :(得分:0)

你可能不得不在这一步上运行动态SQL - 查询所有具有名为EquipmentId的列的表的系统表,并构建一个动态SQL语句,查询每个表是否存在您需要的特定EquipmentId

编辑:@ mellamokb似乎更容易 - 试试。

答案 5 :(得分:0)

这可以使用LEFT JOIN来实现。首先,我们需要一个基表来保存我们正在寻找的EquipmentID的某些值

CREATE TABLE #CertainValues
(
    EquipmentID int
)
INSERT INTO #CertainValues(EquipmentID) VALUES (1)
INSERT INTO #CertainValues(EquipmentID) VALUES (2)
INSERT INTO #CertainValues(EquipmentID) VALUES (3)

然后,我们可以使用各自的[EquipmentID]字段将135个已知表连接到此基表。为避免由于[EquipmentID]出现在一个表的多行中而导致基数问题(重复),最好使用子查询来获取135个表中每个[EquipmentID]的计数。

SELECT
    CV.EquipmentID,
    ISNULL(T001.CNT, 0) AS T001,
    ISNULL(T002.CNT, 0) AS T002,
    ...
    ISNULL(T134.CNT, 0) AS T134,
    ISNULL(T135.CNT, 0) AS T135
FROM
    #CertainValues AS CV
    LEFT OUTER JOIN (SELECT EquipmentID, SUM(1) AS CNT FROM Table001 GROUP BY EquipmentID) AS T001 ON CV.EquipmentID = T001.EquipmentID
    LEFT OUTER JOIN (SELECT EquipmentID, SUM(1) AS CNT FROM Table002 GROUP BY EquipmentID) AS T002 ON CV.EquipmentID = T002.EquipmentID
    ...
    LEFT OUTER JOIN (SELECT EquipmentID, SUM(1) AS CNT FROM Table134 GROUP BY EquipmentID) AS T134 ON CV.EquipmentID = T134.EquipmentID
    LEFT OUTER JOIN (SELECT EquipmentID, SUM(1) AS CNT FROM Table135 GROUP BY EquipmentID) AS T135 ON CV.EquipmentID = T135.EquipmentID

这也为我们提供了一个更有意义的结果集,它显示了我们正在寻找的每个特定值的每个表的行数。以下是结果集示例:

EquipmentID  T001  T002  ...  T134  T135
-----------  ----  ----  ...  ----  ----
          1     0     1  ...     2     3 
          2     3     2  ...     1     0 
          3     0     0  ...     0     0