Điều này sẽ làm những gì bạn muốn. Nó khá xấu xí, nhưng nó sẽ hoàn thành công việc. Chỉ cần dán một truy vấn vào biến @query và nhấn F5; đầu ra là truy vấn mới của bạn. Bạn cần phải thay thế bất kỳ dấu nháy đơn nào bằng hai dấu nháy đơn để nhận được truy vấn chính xác vào biến.
Để tự động dọn dẹp một loạt các truy vấn, bạn có thể biến điều này thành sproc và viết điều gì đó để trỏ qua tệp truy vấn, kéo văn bản của chúng vào biến, chuyển biến cho sproc và xuất kết quả đến tập tin mới.
Declare @query Varchar(Max),
@columns Varchar(Max),
@from Varchar(Max),
@check Int = -1,
@checkChar Varchar(1),
@counter Int = 0,
@newColumns Varchar(Max);;
Declare @indexes Table (tID Int Identity, indexLoc Int, indexChar Varchar(1))
Declare @colNames Table (tID Int, colName Varchar(512))
Set @query =
'SELECT O1890255.LEAF_DETAILS, O1890286.ACTIVITY, O1890258.LEAF_DETAILS_DESCR, O1890261.LEAF_DETAILS, O1890261.LEAF_DETAILS_DESCR, O1890286.BUSINESS_UNIT, O1890286.PROJECT_DESCR, O1890287.PROJECT_ID, O1890288.LEAF_DETAILS, O1890288.LEAF_DETAILS_DESCR, O1890287.SUB_PROJECT, O1890287.SYSTEM_SOURCE, O1890287.YEAR, SUM(O1890287.RESOURCE_AMT_BUD), SUM(O1890287.RESOURCE_AMT_ACT), (SUM(DECODE(O1890287.ACCOUNTING_PERIOD,''8'',O1890287.RESOURCE_AMT_ACT,0)))-(SUM(DECODE(O1890287.ACCOUNTING_PERIOD,''8'',O1890287.RESOURCE_AMT_BUD,0))), SUM(DECODE(O1890287.ACCOUNTING_PERIOD,''8'',O1890287.RESOURCE_AMT_BUD,0)), SUM(DECODE(O1890287.ACCOUNTING_PERIOD,''8'',O1890287.RESOURCE_AMT_ACT,0)), SUM(O1890287.RESOURCE_AMT_ACT-O1890287.RESOURCE_AMT_BUD)
FROM WAREHOUSE.PPL_RPTD_COST_MGMT01JAN00 O1890255, WAREHOUSE.PPL_RPTD_ACTIVITY_BUDG O1890258, WAREHOUSE.PPL_RPTD_BUD_ITEMS01JAN00 O1890261, WAREHOUSE.PROJECT_DENORMAL_GEN O1890286, WAREHOUSE.PROJ_RES_DENORMAL_GEN O1890287, WAREHOUSE.SRC_TREE_VW O1890288
WHERE ((O1890255.LEAF_DETAILS = O1890287.ACCOUNT) AND (O1890258.LEAF_DETAILS = O1890286.ACTIVITY) AND (O1890261.LEAF_DETAILS = O1890287.BUDGET_ITEM) AND (O1890286.PROJECT_ID = O1890287.PROJECT_ID) AND (O1890288.LEAF_DETAILS = O1890287.SRC)) AND (( (O1890255.LEAF_DETAILS LIKE ''12011'' OR O1890255.LEAF_DETAILS = ''10700'') )) AND (O1890287.ACTIVITY LIKE ''000002F%'') AND (O1890287.SUB_PROJECT <> ''897'' AND O1890287.BUDGET_ITEM <> ''CAPBD'' AND O1890287.SUB_PROJECT <> ''896'') AND (O1890261.LEAF_DETAILS NOT IN (''PLTIS'',''14M00'')) AND (O1890287.ACCOUNTING_PERIOD <= ''8'') AND (O1890287.YEAR = ''2012'') AND (O1890286.BUSINESS_UNIT LIKE ''52110'') AND (O1890287.ACCOUNTING_PERIOD NOT IN (998,999)) AND (O1890287.SYSTEM_SOURCE NOT IN ((''PLT'')))
GROUP BY O1890255.LEAF_DETAILS, O1890286.ACTIVITY, O1890258.LEAF_DETAILS_DESCR, O1890261.LEAF_DETAILS, O1890261.LEAF_DETAILS_DESCR, O1890286.BUSINESS_UNIT, O1890286.PROJECT_DESCR, O1890287.PROJECT_ID, O1890288.LEAF_DETAILS, O1890288.LEAF_DETAILS_DESCR, O1890287.SUB_PROJECT, O1890287.SYSTEM_SOURCE, O1890287.YEAR'
Set @from = Right(@query,Len(@query)-(CharIndex('FROM',@query)-1))
Set @columns = Replace(Replace(Replace(@query,@from,''),'SELECT',''),' ','')
While 1 = 1
Begin
Select @check = Min(val)
From (Select CharIndex(',',@columns,@check + 1) As val
Union
Select CharIndex('(',@columns,@check + 1)
Union
Select CharIndex(')',@columns,@check + 1)) As n
If (@check = 0)
Begin
Break
End
Insert @indexes
Select @check, Substring(@columns,@check,1)
End
Delete i1
From @indexes i1
Join @indexes i2
On i1.tID = i2.tID+1
And i1.indexChar = '('
And i2.indexChar = '('
Delete i1
From @indexes i1
Join @indexes i2
On i1.tID = i2.tID-1
And i1.indexChar = ')'
And i2.indexChar = ')'
Declare @indexLoc Int,
@indexChar Varchar(1)
Declare cur Cursor For
Select indexLoc,
indexChar
From @indexes;
Open cur;
Fetch Next
From cur
Into @indexLoc,
@indexChar
Select @checkChar = (Select Top 1 indexChar
From @indexes
Order By tID)
While @@Fetch_Status = 0
Begin
If @indexChar = '('
Begin
Set @counter = @counter + 1;
End
Else If @indexChar = ')'
Begin
Set @counter = @counter - 1;
End
If @counter > 0
Begin
Delete i
From @indexes i
Where indexLoc = @indexLoc
Set @checkChar = @indexChar
End
Fetch Next
From cur
Into @indexLoc,
@indexChar
End
Close cur;
Deallocate cur;
With buildBase As
(
Select 0 As tID, 0 As indexLoc, ',' As indexChar
Union All
Select Row_Number() Over (Order By tID), indexLoc, indexChar
From @indexes
Where indexChar Not In ('(',')')
Union All
Select Count(1) + 1, Len(@columns), ','
From @indexes
Where indexChar Not In ('(',')')
), seperateColumns As
(
Select Row_Number() Over (Order By i1.tID) as tID,
Substring(@columns,i1.indexLoc + 1,i2.indexLoc-(i1.indexLoc+1)) As colName
From buildBase i1
Join buildBase i2
On i1.tID = i2.tID-1
), newNames As
(
Select tID,
Case
When colName Like '%(%'
Then colName +
' [Column' + Convert(Varchar(10),Row_Number() Over (Partition By Case
When colName like '%(%' Then 1
Else 0
End
Order By tID)) + ']'
Else colName +
' [' + Right(colName,Len(colName)-CharIndex('.',colName)) +
Convert(Varchar(10),Row_Number() Over (Partition By Right(colName,Len(colName)-CharIndex('.',colName))
Order By tID)) + ']'
End As colName
From seperateColumns
)
Insert @colNames
Select tID, colName
From newNames
Order By tID
Select @newColumns = COALESCE(@newColumns + ', ', '') + colName
From @colNames
Order By tID
Select 'SELECT ' + @newColumns + ' ' + @from
Output:
SELECT O1890255.LEAF_DETAILS [LEAF_DETAILS1], O1890286.ACTIVITY [ACTIVITY1], O1890258.LEAF_DETAILS_DESCR [LEAF_DETAILS_DESCR1], O1890261.LEAF_DETAILS [LEAF_DETAILS2], O1890261.LEAF_DETAILS_DESCR [LEAF_DETAILS_DESCR2], O1890286.BUSINESS_UNIT [BUSINESS_UNIT1], O1890286.PROJECT_DESCR [PROJECT_DESCR1], O1890287.PROJECT_ID [PROJECT_ID1], O1890288.LEAF_DETAILS [LEAF_DETAILS3], O1890288.LEAF_DETAILS_DESCR [LEAF_DETAILS_DESCR3], O1890287.SUB_PROJECT [SUB_PROJECT1], O1890287.SYSTEM_SOURCE [SYSTEM_SOURCE1], O1890287.YEAR [YEAR1], SUM(O1890287.RESOURCE_AMT_BUD) [Column1], SUM(O1890287.RESOURCE_AMT_ACT) [Column2], (SUM(DECODE(O1890287.ACCOUNTING_PERIOD,'8',O1890287.RESOURCE_AMT_ACT,0)))-(SUM(DECODE(O1890287.ACCOUNTING_PERIOD,'8',O1890287.RESOURCE_AMT_BUD,0))) [Column3], SUM(DECODE(O1890287.ACCOUNTING_PERIOD,'8',O1890287.RESOURCE_AMT_BUD,0)) [Column4], SUM(DECODE(O1890287.ACCOUNTING_PERIOD,'8',O1890287.RESOURCE_AMT_ACT,0)) [Column5], SUM(O1890287.RESOURCE_AMT_ACT-O1890287.RESOURCE_AMT_BUD) [Column6] FROM WAREHOUSE.PPL_RPTD_COST_MGMT01JAN00 O1890255, WAREHOUSE.PPL_RPTD_ACTIVITY_BUDG O1890258, WAREHOUSE.PPL_RPTD_BUD_ITEMS01JAN00 O1890261, WAREHOUSE.PROJECT_DENORMAL_GEN O1890286, WAREHOUSE.PROJ_RES_DENORMAL_GEN O1890287, WAREHOUSE.SRC_TREE_VW O1890288 WHERE ((O1890255.LEAF_DETAILS = O1890287.ACCOUNT) AND (O1890258.LEAF_DETAILS = O1890286.ACTIVITY) AND (O1890261.LEAF_DETAILS = O1890287.BUDGET_ITEM) AND (O1890286.PROJECT_ID = O1890287.PROJECT_ID) AND (O1890288.LEAF_DETAILS = O1890287.SRC)) AND (( (O1890255.LEAF_DETAILS LIKE '12011' OR O1890255.LEAF_DETAILS = '10700') )) AND (O1890287.ACTIVITY LIKE '000002F%') AND (O1890287.SUB_PROJECT <> '897' AND O1890287.BUDGET_ITEM <> 'CAPBD' AND O1890287.SUB_PROJECT <> '896') AND (O1890261.LEAF_DETAILS NOT IN ('PLTIS','14M00')) AND (O1890287.ACCOUNTING_PERIOD <= '8') AND (O1890287.YEAR = '2012') AND (O1890286.BUSINESS_UNIT LIKE '52110') AND (O1890287.ACCOUNTING_PERIOD NOT IN (998,999)) AND (O1890287.SYSTEM_SOURCE NOT IN (('PLT'))) GROUP BY O1890255.LEAF_DETAILS, O1890286.ACTIVITY, O1890258.LEAF_DETAILS_DESCR, O1890261.LEAF_DETAILS, O1890261.LEAF_DETAILS_DESCR, O1890286.BUSINESS_UNIT, O1890286.PROJECT_DESCR, O1890287.PROJECT_ID, O1890288.LEAF_DETAILS, O1890288.LEAF_DETAILS_DESCR, O1890287.SUB_PROJECT, O1890287.SYSTEM_SOURCE, O1890287.YEAR
Ít nhất trên sqlfiddle, có cột trùng lặp sẽ chỉ hiển thị một trong số họ; thêm bí danh, tuy nhiên, sẽ hiển thị cả hai. Xem này http://sqlfiddle.com/#!4/4f184/6 fiddle, Bạn có nhận được bất kỳ lỗi nào khi bạn chạy truy vấn này? – Isaac