2016-08-04 45 views
0

我是Microsoft SQL Server 2008的新手。我需要一些幫助從多個表中檢索具有相同數據類型的相同列的數據。如何從SQL Server中的多個日常表中檢索數據

目前我在我的數據庫中有多個表,每個表包含一天的數據。例如,我有如下表:

  • Table_20160820
  • Table_20160821
  • Table_20160822
  • Table_20160823
  • Table_20160824
  • Table_20160825

所有表具有相同的同一列數據類型說:

  • COLUMN_1
  • COLUMN_2
  • column_3
  • column_4

現在,是有可能從使用單個查詢的所有表中獲取列。

我正在尋找的是獲取column_3的計數,將根據column_1對所有表進行分組。我想避免編寫多個查詢,因爲我需要從整個30個表格中提取整個月份的數據。

+10

不同的表爲不同的日期......聽起來像一個壞主意。 (有一張表,添加一個日期列!) – jarlh

+5

同意@jarlh:這是一個**可怕的糟糕的設計,並且會讓你的生活成爲數據庫開發者一個活生生的地獄!修復設計 - 不要浪費時間試圖「優化」訪問這個混亂.... –

回答

1

正如評論所說,最好將它組織成一張表,然後添加一個日期列,以便您可以查看每行何時添加。您甚至可以將date_created列的默認值設置爲getdate()

要將所有數據放在一起,請將UNION運算符連同對新的更好的表的insert語句一起使用。

CREATE TABLE Better_Table (Column_1 <type>, Column_2 <type>, ..., Date_Created DateTime2(7) Default GETDATE()) 
GO 
INSERT INTO Better_Table (Column_1, Column_2, ...) 
SELECT *, '2016/08/22' FROM Table_20160822 
UNION 
SELECT *, '2016/08/23' FROM Table_20160823 
... 

一旦你做到了這一點您的查詢就會簡單得多:

SELECT Column_1, COUNT(Column_3) 
FROM Better_Table 
WHERE date_created >= '2016/08/01' 
AND date_created < '2016/09/01' 
GROUP BY Column_1 

雖然你仍然可以做到這一點在DB當前狀態由group by查詢中使用union運算符。它看起來像這樣:

SELECT a.column_1, COUNT(a.column_3) 
FROM ( 
SELECT column_1, Column_3 
FROM Table_20160822 
UNION ALL 
SELECT column_1, Column_3 
FROM Table_20160823 
) a 
GROUP BY a.Column_1 

只需將其展開到需要抓取的表格即可。

+0

嗨,你已經提到,它會更好地創建一個新的表。我正在嘗試通過使用SELECT * INTO命令。但由於某種原因,它不會創建包含所有列的新表。 –

+0

@Ajitav雅你需要創建表,然後才能插入它。我已經更新了我的答案,以展示如何做到這一點。 – Phritzy

0

您可以使用CTE來得到你需要的,然後創建一個查詢所有日期和執行:

DECLARE @dateStart datetime = '2016-08-01', 
     @dateFinish datetime = '2016-09-01', 
     @query nvarchar(max) 

;WITH cte as (
SELECT @dateStart as d 
UNION ALL 
SELECT DATEADD(day,1,d) 
FROM cte 
WHERE DATEADD(day,1,d) < @dateFinish 
) 

SELECT @query = (

    SELECT 'SELECT column_1, COUNT(column_3) FROM (' 
    + STUFF((
    SELECT ' UNION ALL SELECT * FROM [Table_'+CONVERT(nvarchar(8),d,112)+'] ' 
    FROM cte 
    FOR XML PATH('') 
    ),1,10,'') + ') as t GROUP BY column_1 ' 
    FOR XML PATH('') 
) 

PRINT @query 

EXEC sp_executesql @query 

輸出@query變量:

SELECT column_1, COUNT(column_3) 
FROM ( 
    SELECT * FROM [Table_20160801] UNION ALL 
    SELECT * FROM [Table_20160802] UNION ALL 
    SELECT * FROM [Table_20160803] UNION ALL 
    SELECT * FROM [Table_20160804] UNION ALL 
    .... 
    SELECT * FROM [Table_20160831] 
) as t 
GROUP BY column_1 
0

如上所述,這是一個不好的設計如果設計在第一個地方是固定的,那就太好了。這是一項技術性債務,遲早必須償還。反正這裏是你如何能做到這一點:

DECLARE @dtStartDate  DATE, 
     @dtEndDate   DATE, 
     @nvchTablePrefix NVARCHAR(50), 
     @nvchQuery   NVARCHAR(max) 


SELECT @dtStartDate = '20160801', 
     @dtEndDate = '20160831', 
     @nvchTablePrefix = 'Table_' 


CREATE TABLE #temp 
(name NVARCHAR(100)) 

WHILE(@dtStartDate <= @dtEndDate) 
BEGIN 
INSERT INTO #temp 
SELECT ' SELECT column_1, column_3 FROM ' + @nvchTablePrefix + CONVERT(NVARCHAR,@dtStartDate,112) 

SELECT @dtStartDate = DATEADD(d,1,@dtStartDate) 

IF (@dtStartDate <= @dtEndDate) 
INSERT INTO #temp 
SELECT ' UNION ' 
END 



SELECT @nvchQuery = 'SELECT column_1, COUNT(column_3) as column3count FROM (' 

SELECT @nvchQuery = @nvchQuery + name FROM #temp 

SELECT @nvchQuery = @nvchQuery + ') t GROUP BY column1' 



PRINT @nvchQuery 
EXEC sp_executesql @nvchQuery 


DROP TABLE #temp 

print語句的輸出將類似 -

SELECT column_1, COUNT(column_3) as column3count 
FROM 
( SELECT column_1, column_3 FROM Table_20160801 
    UNION 
    SELECT column_1, column_3 FROM Table_20160802 
    UNION 
    .... 
    UNION 
    SELECT column_1, column_3 FROM Table_20160831 
) t GROUP BY column1 
相關問題