Sql-Server

為具有相似列但表名不同的表重構 sql

  • November 4, 2014

我的任務是重構一個從不同表執行大量聯合的 SQL 腳本。這些表具有相似的資訊,因此腳本會查詢與每個表中相同的列,只是表名不同。例如:

customerTransaction2011_Tbl

|ID | T.ID | Amount |
|---|------|--------|

CustomerTransaction2012_Tbl

|ID | T.ID | Amount |
|---|------|--------|

CustomerTransaction2013_Tbl

|ID | T.ID | Amount |
|---|------|--------|

我必須重構的 SQL 腳本如下:

Select ID, Sum(Amount), '2011' as [Year]
into #Tbl_threeYear
From CustomerTransaction2011_Tbl
union all
Select ID, Sum(Amount), '2012' as [Year]
From CustomerTransaction2012_Tbl
union all
Select ID, Sum(Amount), '2013' as [Year]
From CustomerTransaction2013_Tbl;

為了重新考慮這一點,我曾想過Dynamic SQL在 a中使用stored procedure,這樣我就可以將年份(2011、2012、2013)作為參數傳遞給儲存過程,儲存過程會將這些附加到動態 SQL 字元串中。

但事實證明我無法獲得創建儲存過程的權限。

所以有2個問題,請:

如果我只是Dynamic SQL像這樣使用

declare @sqlmain as varchar(500);
declare @tblPart as varchar(100);
set @tblPart = '2011';
set @sqlmain = 'select ID, sum(Amount) from customerTransaction' + @tblPart + '_Tbl;'

我如何exec(sqlmain)在簡單地更改 @tblPart 變數的同時對結果執行聯合 - 必須以某種方式實現?

另外,您是否願意以另一種方式重構這樣的腳本?由於這是我第一次重構,我非常歡迎任何建議/批評。也許有人可以建議如何重新考慮基本 SQL?

這一切都在 SQL Server 2005 中完成。

非常感激。

這可能會幫助您使用 SQL Server 的 COALESCE 函式為分區表創建簡單的動態查詢

**Step1:**創建分割token的函式

CREATE FUNCTION [dbo].[fnSplit]
(
@List VARCHAR(8000),
@Delimiter CHAR(1) = ','
)
RETURNS @Temp1 TABLE
(
ItemId INT IDENTITY(1, 1)
NOT NULL
PRIMARY KEY,
Item VARCHAR(8000) NULL
)
AS BEGIN

DECLARE @item VARCHAR(4000),
@iPos INT

SET @Delimiter = ISNULL(@Delimiter, ',')
SET @List = RTRIM(LTRIM(@List))

-- check for final delimiter
IF RIGHT(@List, 1) <> @Delimiter 
-- append final delimiter
SELECT @List = @List + @Delimiter

-- get position of first element
SELECT @iPos = CHARINDEX(@Delimiter, @List, 1)

WHILE @iPos > 0
BEGIN
-- get item
SELECT @item = LTRIM(RTRIM(SUBSTRING(@List, 1, @iPos - 1)))
IF @@ERROR <> 0 
BREAK
-- remove item form list
SELECT @List = SUBSTRING(@List, @iPos + 1, LEN(@List) - @iPos + 1)
IF @@ERROR <> 0 
BREAK
-- insert item
INSERT @Temp1
VALUES ( @item )
IF @@ERROR <> 0 
BREAK
-- get position pf next item
SELECT @iPos = CHARINDEX(@Delimiter, @List, 1)
IF @@ERROR <> 0 
BREAK
END
RETURN
END


GO

**第二步:**設置參數值@varyears並執行查詢

DECLARE @varyears VARCHAR(200)
SET @varyears = '2012, 2011, 2013 ,2014'


DECLARE @combinedString VARCHAR(MAX)

SELECT  @combinedString = COALESCE(@combinedString + ' UNION ALL ', '')
       + CHAR(13) + ' Select ID, sum(amount) TotalAmount, ''' + item
       + ''' as [Year] FROM CustomerTransaction' + item
       + '_tbl  group by ID ' + CHAR(13) --group by clause added to your query for using aggregate function 
FROM    dbo.fnSplit(@varyears, ',')


EXEC ( @combinedString )

引用自:https://dba.stackexchange.com/questions/81809