巨型编辑
虽然我同意@Joro 的方法,但我意识到有一种稍微冗长但更简单的方法。
我创建了您的表的副本并将其命名为“课程”,但我只在其中放置了 12 个课程,但您可以以相同的方式生成查询。
使用以下查询(使用INFORMATION_SCHEMA.COLUMNS):
SELECT 'SELECT ID, ''' + COLUMN_NAME + ''' AS LessonName,
[' + COLUMN_NAME + '] AS Lesson ' +
+ 'FROM Lesson WHERE ID = @ID AND LEN([' + COLUMN_NAME + ']) > 2 UNION'
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'Lesson'
AND DATA_TYPE = 'varchar'
我生成一个如下所示的查询:
SELECT ID, 'Lesson 1' AS LessonName, [Lesson 1] AS Lesson
FROM Lesson WHERE ID = @ID AND LEN([Lesson 1]) > 2 UNION
SELECT ID, 'Lesson 2' AS LessonName, [Lesson 2] AS Lesson
FROM Lesson WHERE ID = @ID AND LEN([Lesson 2]) > 2 UNION
... (SQL omitted for brevity)
SELECT ID, 'Lesson 12' AS LessonName, [Lesson 12] AS Lesson
FROM Lesson WHERE ID = @ID AND LEN([Lesson 12]) > 2 UNION
删除最后一个 UNION 并通过将@ID 声明为 35 来运行查询给了我:
|| ID || LessonName || Lesson
|| 35 || Lesson 4 || Maths
|| 35 || Lesson 9 || ICT
|| 35 || Lesson 12 || English
然后我想,好吧,我可能只是使用上面的技术来调整它......但后来我有了另一个 - 我们真正想要的列在 LessonName 列中,所以,我们可能只运行一个动态 SQL 查询这些列名在:
DECLARE @ColumnList VARCHAR(MAX)
SELECT @ColumnList = COALESCE(@ColumnList + ', ','') + '[' + Lessons.LessonName + ']'
FROM (
SELECT ID, 'Lesson 1' AS LessonName, [Lesson 1] AS Lesson FROM Lesson WHERE ID = @ID AND LEN([Lesson 1]) > 2 UNION
SELECT ID, 'Lesson 2' AS LessonName, [Lesson 2] AS Lesson FROM Lesson WHERE ID = @ID AND LEN([Lesson 2]) > 2 UNION
...
SELECT ID, 'Lesson 12' AS LessonName, [Lesson 12] AS Lesson FROM Lesson WHERE ID = @ID AND LEN([Lesson 12]) > 2)
AS Lessons
这给了我结果'[Lesson 4], [Lesson 9], [Lesson 12]'
反过来,您可以执行以下操作:
DECLARE @QuerySQL NVARCHAR(MAX)
SET @QuerySql = 'SELECT ' + CAST(@ID AS VARCHAR) + ' AS ID, ' + @ColumnList + ' FROM Lesson WHERE ID = @ID'
--Query actually looks like: SELECT 35 AS ID, [Lesson 4], [Lesson 9], [Lesson 12]
-- FROM Lesson WHERE ID = 35
DECLARE @ID INT --You will already have done this above anyway really
SET @ID = 35
EXEC sp_executeSQL @QuerySql,N'@ID int', @ID
返回:
|| ID || Lesson 4 || Lesson 9 || Lesson 12
|| 35 || Maths || ICT || English
使用数据透视函数的另一种方法 - 您可以轻松地生成此 sql 一次并将其保留在存储过程中。
因此,总而言之,您的用法如下所示:
DECLARE @ID INT
SET @ID = 35
DECLARE @ColumnList VARCHAR(MAX)
SELECT @ColumnList = COALESCE(@ColumnList + ', ','') + '[' + Lessons.LessonName + ']'
FROM (
SELECT ID, 'Lesson 1' AS LessonName, [Lesson 1] AS Lesson FROM Lesson WHERE ID = @ID AND LEN([Lesson 1]) > 2 UNION
SELECT ID, 'Lesson 2' AS LessonName, [Lesson 2] AS Lesson FROM Lesson WHERE ID = @ID AND LEN([Lesson 2]) > 2 UNION
...
SELECT ID, 'Lesson 35' AS LessonName, [Lesson 35] AS Lesson FROM Lesson WHERE ID = @ID AND LEN([Lesson 35]) > 2)
AS Lessons --Remember you can generate this section quite simply using information_schema.columns
--and you don't actually need the ID or Lesson columns - just the lesson names.
DECLARE @QuerySQL NVARCHAR(MAX)
SET @QuerySql = 'SELECT ' + CAST(@ID AS VARCHAR) + ' AS ID, ' + @ColumnList + ' FROM Lesson WHERE ID = @ID'
EXEC sp_executeSQL @QuerySql,N'@ID int', @ID
这会给你你想要的答案。
请注意,在 GUI 级别旋转数据(通过 Excel Pivot 表或 DevExpress Pivot Grid 等第 3 方组件意味着您可以在第一个结果集 - UNION 查询的输出处停止)