【问题标题】:Is there any way to put subquery in the column list of a SQL query有没有办法将子查询放在 SQL 查询的列列表中
【发布时间】:2021-11-30 08:37:37
【问题描述】:

我正在尝试编写一个 SQL 查询,该查询具有从另一个 SQL 查询生成的列列表。我正在开发 Microsoft SQL Server Management Studio。

这是获取列列表的 SQL 查询

SELECT COLUMN_NAME 
FROM INFORMATION_SCHEMA.COLUMNS 
WHERE TABLE_NAME = 'table_name'

它返回以下内容

|          | COLUMN_NAME    |
| -------- | -------------- |
| 1        | name1          |
| 2        | name2          |
| 3        | name3          |

这是我目前拥有的 SQL 查询,它运行良好

SELECT DISTINCT name1, name2 
FROM [table_catalog].[table_schema].[table_name]

这是它返回的内容

|          | name1          |name2          |
| -------- | -------------- |-------------- |
| 1        | value1         |a1             |
| 2        | value2         |a2             |
| 3        | value3         |a3             |
| 3        | value4         |a1             |

我想做的是得到一个表,其中只包含第一个表中的所有列,像这样

|          | name1          |name2          |name3          |
| -------- | -------------- |-------------- |-------------- |
| 1        | value1         |a1             |b1             |
| 2        | value2         |a2             |b2             |
| 3        | value3         |a3             |b1             |
| 3        | value4         |a1             |b2             |

这是我目前的尝试

SELECT DISTINCT
    (SELECT COLUMN_NAME 
     FROM INFORMATION_SCHEMA.COLUMNS 
     WHERE TABLE_NAME = 'table_name') 
FROM 
    [table_catalog].[table_schema].[table_name]

它没有按预期工作,我也尝试使用 CLE 和其他一些方法来做到这一点。但是,它们都不起作用。我在网上做了一些研究,好像没有多少人做过这种查询,不知道有没有其他的方法呢?我做错了什么?

【问题讨论】:

  • 虽然你的问题不是很清楚,但是好像你在找动态sql
  • 我想我可能需要编写一个 for 循环来生成列列表?
  • 最后一列name3的逻辑是什么?您如何将 name1name2 与这些值相关联?
  • “我认为我可能需要编写一个 for 循环” 不太可能。 SQL 是一种基于集合的语言,如果您正在编写循环,那么您可能做错了。
  • 嗨松鼠。这是一个错字。我已经修复了它们。这些是每列的随机值。

标签: sql sql-server tsql


【解决方案1】:

您必须为此使用动态 sql。
这是一个一步一步的小例子。完整的代码在最后。

首先我们需要检索变量中的列名。我们希望这个变量填充来自table_name 的所有列并用逗号分隔。这就是为什么我们使用for XML path('') stuff 用于转储第一个逗号。

declare @ColNames varchar(max)

select @ColNames = stuff(( select ', ' + column_name
                           from   INFORMATION_SCHEMA.COLUMNS
                           where  table_name = 'table_name'
                           for XML path('')
                          ), 1, 2, '')

变量@ColNames 的内容将如下所示

name1, name2, name3

这样我们就可以在变量中构建我们的 sql 语句了

declare @sql varchar(max)
set @sql = 'select ' + @ColNames + ' from table_name'

最后我们执行它

exec(@sql)

这应该会给你你需要的结果。

当然,您也可以将表名table_name 放入一个变量中,这样会更加灵活。
完整代码如下:

declare @TableName varchar(100) = 'SomeTableName'

declare @ColNames varchar(max)
select @ColNames = stuff(( select ', ' + column_name
                           from   INFORMATION_SCHEMA.COLUMNS
                           where  table_name = @TableName
                           for XML path('')
                          ), 1, 2, '')

declare @sql varchar(max)
set @sql = 'select ' + @ColNames + ' from ' + @TableName

exec(@sql)

【讨论】:

  • 您好,谢谢。如果这个答案解决了您的问题,那么请考虑投票和/或接受这个作为答案。现在关于 stuff 命令中的 1、2。 XML 的选择将产生如下结果:, name1, name2, name3 和东西 1, 2, '' 表示我想从位置 1 用 '' 替换 2 个字符,所以结果现在是 name1, name2, name3
  • 您好 GuidoG,非常感谢您的回答。这正是我正在寻找的。但是,我运行的代码并没有按预期运行。它没有显示我正在寻找的表格。因此,我检查了您的代码并尝试打印(@ColNames)但没有打印出来。我想知道除了@TableName 之外还有什么需要编辑的吗?
  • 它对我有用,您复制/粘贴的代码是否完全相同?是的,您只需要编辑 TableName 变量
  • 感谢您的回复。我赞成你的回答。也谢谢你的解释。这真的很有帮助。
  • 我刚刚在 MSSM 中尝试过,它工作正常,我得到返回的结果没有问题
猜你喜欢
  • 2019-07-12
  • 1970-01-01
  • 2018-08-14
  • 1970-01-01
  • 1970-01-01
  • 2021-12-08
  • 1970-01-01
  • 2010-09-08
  • 1970-01-01
相关资源
最近更新 更多