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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何编写一个查询以从SQL Server中包含类似名称的多个表中获取数据相关的知识,希望对你有一定的参考价值。

从开始,我无法更改表的命名约定。但是我想对每个表运行相同的查询而不必每次都进入并更改表名。我的表格如下:

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

从客户记录我将拉CustomerNameAccountAddress

从每个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

(这会产生一切,但是我不能过滤掉更多,不包括EVENTNAME的“OPEN”,“CLOSE”,“TEST”。他们只想看到实际的报警线)

我试过了:

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')

(这个比较糟糕的是我必须每个月更换一次CLOG(120次)

谢谢你的帮助!我正在通过反复试验......没有正式的培训。

解决方案,感谢BRIAN! 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
    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
答案

Brian回答。谢谢Brian!解决方案 - 我没有正确格式化我的EVENTNAME NOT IN列表

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

以上是关于如何编写一个查询以从SQL Server中包含类似名称的多个表中获取数据的主要内容,如果未能解决你的问题,请参考以下文章

进行查找并编写查询以从 sql server 获取数据

SQL Server 2008 查询以查找列中包含非字母数字字符的行

SQL Server 索引中包含查询字段 (INCLUDE索引)

Oracle环境,求一个sql语句,如何查询某字段(bz)中包含三个英文字母的连写记录?

如何在 JPA 中编写动态 sql 查询以从 jsonb 列中查询数据?

如何编写 SQL 查询以从表中提取 50% 的记录?