如何编写一个查询以从SQL Server中包含相似名称的多个表中获取数据

时间:2019-03-12 19:38:22

标签: sql sql-server database

首先,我不能更改表的命名约定。但是我想对每个表运行相同的查询,而不必每次都更改表名。我的表格如下:

Customer
------------
CLOG201902
CLOG201901
CLOG201812.....(one per month going back 10 years. The average CLOG table contains 200,000 lines. 

从客户记录中,我将拉出CustomerNameAccountAddress

我将从EACH CLOG表中提取日期,时间,EventType等。

过滤依据:Customer.instno = 38(仅需要拉出该安装程序的编号),并且仅进行相关的警报活动(火灾,盗窃等)

我已经尝试过(为什么在代码底部无法正常工作):

DECLARE @sql AS NVARCHAR(MAX) = ''

SELECT @sql = @sql + N'
SELECT DISTINCT 
    CUSTID
    , KEYALM
    , CUSTPRIV.NAME AS "PROPERTY NAME"
    , EVENTNAME AS "ALARM TYPE"
    , EVSTRING
    , ZONE
    , POINTID
    , USRNO
    , CUSTOMER.BRANCHNO
FROM ['+ SCHEMA_NAME(schema_id) +'].' + name + '  INNER JOIN
    CUSTOMER ON CUSTOMER.SERIALNO = ['+ SCHEMA_NAME(schema_id) +'].' + name + ' .SERIALNO INNER JOIN
    CUSTPRIV ON CUSTOMER.SERIALNO = CUSTPRIV.SERIALNO
WHERE KEYALM IS NOT NULL
    AND BRANCHNO = 38
    AND EVENTNAME IS NOT NULL
UNION ALL '
FROM sys.tables where name like 'clog2019%'

SELECT @sql = SUBSTRING(@sql, 0, len(@sql)-9)

SELECT @sql 
exec sp_executesql @SQL

(这确实产生了一切,但是我不能进一步过滤,不包括“打开”,“关闭”,“测试”的事件名称。他们只想查看实际的警报行)

我尝试过:

DECLARE @sql NVARCHAR(MAX);

SELECT @sql = STUFF
((
     SELECT ' UNION ALL SELECT  FROM ' + NAME AS [text()]
     FROM sys.tables
     WHERE NAME LIKE 'CLOG2019%' 
     FOR XML PATH('')
) ,1,11,'');

EXEC sp_executesql @sql;

这还会返回每一行,我似乎根本无法使用where子句进行过滤。

如果我要分别运行每个月的查询,它将如下所示:

SELECT DISTINCT 
    CONVERT(varchar,EVDATE,(1)) AS DATE
    , CONVERT(VARCHAR,EVDATE,(8)) AS TIME
    , CUSTID
    , KEYALM
    , EVENTNAME
    , EVSTRING
    , ZONE
    , POINTID
    , USRNO
    , CUSTOMER.BRANCHNO
FROM CLOG201902  INNER JOIN
    CUSTOMER ON CUSTOMER.SERIALNO = CLOG201902.SERIALNO INNER JOIN
    CUSTPRIV ON CUSTOMER.SERIALNO = CUSTPRIV.SERIALNO
WHERE KEYALM IS NOT NULL
    AND BRANCHNO = 38
    AND (EVENTNAME LIKE 'CRITICAL'
        OR EVENTNAME LIKE 'FIRE'
        OR EVENTNAME LIKE 'BURGLARY')

(最糟糕的部分是我必须每月(120次)更改CLOG

感谢您的帮助!我正在反复试验中学习……没有经过正式培训。

解决方案,谢谢布莱恩!     宣告@sql AS nvarchar(max)=''

SELECT @sql = @sql + N'
SELECT DISTINCT 
    CUSTID
    , KEYALM
    , CUSTPRIV.NAME AS "PROPERTY NAME"
    , EVENTNAME AS "ALARM TYPE"
    , EVSTRING
    , ZONE
    , POINTID
    , USRNO
    , CUSTOMER.BRANCHNO
FROM ['+ SCHEMA_NAME(schema_id) +'].' + name + '  INNER JOIN
    CUSTOMER ON CUSTOMER.SERIALNO = ['+ SCHEMA_NAME(schema_id) +'].' + name + ' .SERIALNO INNER JOIN
    CUSTPRIV ON CUSTOMER.SERIALNO = CUSTPRIV.SERIALNO
WHERE KEYALM IS NOT NULL
    AND BRANCHNO = 38
    AND EVENTNAME IS NOT NULL
    AND EVENTNAME NOT IN (''OPEN'', ''CLOSE'', ''TEST'') --double single quotes made the error go away and worked! 20,000 rows down to 1,061!

UNION ALL '
FROM sys.tables where name like 'clog2019%'


SELECT @sql = SUBSTRING(@sql, 0, len(@sql)-9)

SELECT @sql 


exec sp_executesql @SQL

1 个答案:

答案 0 :(得分:0)

由Brian解答。谢谢布莱恩!解决方案-我没有正确设置“ EVENTNAME不在列表”中的格式

SELECT @sql = @sql + N'
SELECT DISTINCT 
    CUSTID
    , KEYALM
    , CUSTPRIV.NAME AS "PROPERTY NAME"
    , EVENTNAME AS "ALARM TYPE"
    , EVSTRING
    , ZONE
    , POINTID
    , USRNO
    , CUSTOMER.BRANCHNO
FROM ['+ SCHEMA_NAME(schema_id) +'].' + name + '  INNER JOIN
    CUSTOMER ON CUSTOMER.SERIALNO = ['+ SCHEMA_NAME(schema_id) +'].' + name + ' .SERIALNO INNER JOIN
    CUSTPRIV ON CUSTOMER.SERIALNO = CUSTPRIV.SERIALNO
WHERE KEYALM IS NOT NULL
    AND BRANCHNO = 38
    AND EVENTNAME IS NOT NULL
    AND EVENTNAME NOT IN (''OPEN'', ''CLOSE'', ''TEST'') --double single quotes made the error go away and worked! 20,000 rows down to 1,061!

UNION ALL '
FROM sys.tables where name like 'clog2019%'


SELECT @sql = SUBSTRING(@sql, 0, len(@sql)-9)

SELECT @sql 


exec sp_executesql @SQL