-- Create temp tables and sample data
CREATE TABLE ##tblReports (books INT, groupid INT, category VARCHAR(25), [01-01-2014] INT, [02-01-2014] INT)
INSERT INTO ##tblReports VALUES (100, 1, 'Limit', 700, 0), (100, 1, 'Exp', 70, 0), (100, 1, 'Balance', 630, 0),
(200, 1, 'Limit', 0, 900), (200, 1, 'Exp', 0, 100), (200, 1, 'Balance', 0, 800)
CREATE TABLE ##tblLimits (groupid INT, [100bookslimit] INT, [200bookslimit] INT)
INSERT INTO ##tblLimits VALUES (1, 700, 900), (2, 7, 10)
-- Unpivot ##tblLimits in a CTE (see footnote for what this outputs)
DECLARE @sql NVARCHAR(MAX)
SELECT @sql = '
;WITH cte_unpivot AS
(
SELECT groupid, val, CAST(REPLACE(col, ''bookslimit'', '''') AS INT) AS books
FROM ##tblLimits
UNPIVOT (val FOR col IN ('
-- Are the columns in ##tblLimits dynamic (other than groupid)? If so, get their
-- names from tempdb.sys.columns metadata.
SELECT @sql += QUOTENAME(name) + ',' -- [Column],
FROM tempdb.sys.columns
WHERE [object_id] = OBJECT_ID(N'tempdb..##tblLimits') AND name <> 'groupid'
-- Delete trailing comma
SELECT @sql = SUBSTRING(@sql, 1, LEN(@sql) - 1)
SELECT @sql += '))AS u
)
SELECT t.books, t.groupid, category,
'
-- Get ##tblReports column names from tempdb.sys.columns metadata.
SELECT @sql += '
CASE WHEN ' + QUOTENAME(name) + ' = 0 AND t.category IN (''Limit'', ''Balance'')
THEN c.val ELSE t.' + QUOTENAME(name) + ' END AS ' + QUOTENAME(name) + ','
FROM tempdb.sys.columns
WHERE [object_id] = OBJECT_ID(N'tempdb..##tblReports') AND name NOT IN ('books', 'groupid', 'category')
-- Delete trailing comma again
SELECT @sql = SUBSTRING(@sql, 1, LEN(@sql) - 1)
SELECT @sql += '
FROM ##tblReports t
LEFT JOIN cte_unpivot c ON t.books = c.books AND t.groupid = c.groupid
'
EXEC sp_executesql @sql
回报:
books groupid category 01-01-2014 02-01-2014
100 1 Limit 700 700
100 1 Exp 70 0
100 1 Balance 630 700
200 1 Limit 900 900
200 1 Exp 0 100
200 1 Balance 900 800
关键是将##tblLimits 转换为这种格式,以便您可以轻松地将其加入##tblReports:
groupid val books
1 700 100
1 900 200
2 7 100
2 10 200
这是它生成的 SQL(但已格式化):
;WITH cte_unpivot
AS (SELECT groupid,
val,
Cast(Replace(col, 'bookslimit', '') AS INT) AS books
FROM ##tbllimits
UNPIVOT (val
FOR col IN ([100bookslimit],
[200bookslimit]))AS u)
SELECT t.books,
t.groupid,
category,
CASE
WHEN [01-01-2014] = 0
AND t.category IN ( 'Limit', 'Balance' ) THEN c.val
ELSE t.[01-01-2014]
END AS [01-01-2014],
CASE
WHEN [02-01-2014] = 0
AND t.category IN ( 'Limit', 'Balance' ) THEN c.val
ELSE t.[02-01-2014]
END AS [02-01-2014]
FROM ##tblreports t
LEFT JOIN cte_unpivot c
ON t.books = c.books
AND t.groupid = c.groupid