如果字符串长度大于2,则选择"仅列"

Zee*_*pro 2 sql t-sql

可能会问类似问题,但我无法找到符合我需求的任何内容.

如何仅选择字符串长度大于2的列

这已经做了多少.

SELECT * FROM Table1

WHERE (Table1.ID = @ID)
Run Code Online (Sandbox Code Playgroud)

或类似的东西

WHERE (Table1.ID = @ID) AND (LEN(*) > 2)
Run Code Online (Sandbox Code Playgroud)

感谢您的所有帮助

我有一个表,其中我有35列和一个用户ID列,现在我想从只有> 2字符串的列中选择和显示信息.

我喜欢只选择具有> 2字符串和用户定义的ID而不是整行的列!

我希望我有意义.

在此输入图像描述

期望的结果

在此输入图像描述

das*_*ash 6

GIANT EDIT

虽然我同意@ Joro的方法,但我意识到有一种稍微冗长但更简单的方法.

我创建了一个表的副本并将其命名为Lessons,但我只在其中放入了12个Lessons,但您可以以相同的方式生成查询.

使用以下查询(使用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'
Run Code Online (Sandbox Code Playgroud)

我生成一个看起来像这样的查询:

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
Run Code Online (Sandbox Code Playgroud)

通过将@ID声明为35来删除最后一个UNION并运行查询,这给了我:

|| ID || LessonName || Lesson
|| 35 || Lesson 4   || Maths
|| 35 || Lesson 9   || ICT
|| 35 || Lesson 12  || English
Run Code Online (Sandbox Code Playgroud)

然后我自己想,好吧,我可能只是使用上面的技术来调整它...但是我有另一个 - 我们实际想要的列是在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
Run Code Online (Sandbox Code Playgroud)

这给了我结果 '[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
Run Code Online (Sandbox Code Playgroud)

哪个回报:

|| ID || Lesson 4 || Lesson 9 || Lesson 12 
|| 35 || Maths    || ICT      || English
Run Code Online (Sandbox Code Playgroud)

使用pivot函数的另一种方法 - 您可以轻松生成此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 
Run Code Online (Sandbox Code Playgroud)

哪个会给你你想要的答案.

请注意,在GUI级别转动数据(通过Excel Pivot表或第三方组件,如DevExpress Pivot Grid,意味着您可以停在第一个结果集 - UNION查询的输出)


got*_*tqn 6

我还没有设法只使用一个动态构建的T-SQL语句.以下是您应该做的以获得所需的结果:

创建临时表来存储结果:

DECLARE @DynamicSQLStatement NVARCHAR(MAX)

CREATE TABLE #DataSource
(
     [Id] BIGINT 
    ,[SubjectName] NVARCHAR(100)
    ,[Lesson] NVARCHAR(100)
)
Run Code Online (Sandbox Code Playgroud)

使用特定数据初始化临时表:

SET @DynamicSQLStatement=N' INSERT INTO #DataSource ([Id],[SubjectName],[Lesson])
                            SELECT   [Id]
                                    ,[SubjectName]
                                    ,[Lesson]
                            FROM SourceTable
                            UNPIVOT 
                            (
                                [SubjectName] FOR [Lesson] IN ('+(SELECT SUBSTRING((SELECT '],[' + COLUMN_NAME FROM INFORMATION_SCHEMA.Columns  WHERE TABLE_NAME = 'SourceTable' AND COLUMN_NAME<>'ID' FOR XML PATH('')),3,300)+']')+')
                            ) as pvt
                            WHERE ID=35 AND LEN([SubjectName])>2'

EXECUTE sp_executesql @DynamicSQLStatement
Run Code Online (Sandbox Code Playgroud)

现在,我们在其中有这些记录:

在此输入图像描述

请注意限制结果的"WHERE"子句.此外,'SourceTable'应替换为您的表名称.我正在做的是获取此表的所有列而不使用"Id",但您可以在没有sp_exetuesql的情况下执行此操作,只需写下所有列:

INSERT INTO #DataSource ([Id],[SubjectName],[Lesson])
SELECT   [Id]
        ,[SubjectName]
        ,[Lesson]
FROM SourceTable
UNPIVOT 
(
    [SubjectName] FOR [Lesson] IN ([Lesson 1],[Lesson 2],[Lesson 3],...,[Lesson n])
) as pvt
WHERE ID=35 AND LEN([SubjectName])>2'
Run Code Online (Sandbox Code Playgroud)

这是最后一个 - 以期望格式获取结果并删除临时表:

SET @DynamicSQLStatement=N' SELECT *
                            FROM #DataSource
                            PIVOT
                            (
                                MAX([SubjectName]) FOR [Lesson] IN ('+ (SELECT SUBSTRING((SELECT '],[' + Lesson FROM #DataSource FOR XML PATH('')),3,100)+']')+')
                            )AS ResultTable'

EXECUTE sp_executesql @DynamicSQLStatement

DROP TABLE #DataSource
Run Code Online (Sandbox Code Playgroud)

这是最终的结果:

在此输入图像描述

我希望这对你有意义.我真的很失望,我只能通过一个声明来做到这一点.如果有人能够,那将是非常有趣的技术.

如果我是你,我将从这个代码存储过程中使用参数创建列和用户ID中文本的最小长度.