【问题标题】:How to split a single column into multiple columns in SQL Server select statement?如何在 SQL Server select 语句中将单列拆分为多列?
【发布时间】:2015-04-15 14:12:27
【问题描述】:

我是 SQL Server 新手。我有一个长列,名称从 a、b、c 和 d 开始。我想在 NameA、NameB、NameC 和 NameD 的单独列中显示它们。我尝试了联合,但它显示在一列中。我试过了,但我不知道如何使用它。请帮忙。

现有列

names
A1
B1
A2
C1
A3
A4

A_names| B_names | C_names
A1     | B1      | C1
A2
A3
A4

【问题讨论】:

  • 您可以为每一列使用 CASE 表达式,而不是 UNION。
  • 这是一个奇怪的要求。您如何知道哪个 NameA 与哪个 NameB 匹配?还是没关系?你确定要这个吗?为什么?另外:请提供一些具有期望结果的示例数据。
  • NAME列中的数据是否有分隔符?
  • 请添加一些示例数据,即您的用户表数据和您想要的输出。您很可能在这里要求的不是您真正想要的东西 - 添加示例将有助于您自己和其他人澄清。
  • 很难想出一个用例。你要问的是一个有代表性的事情,你应该在你的应用程序中真正解决它,而不是在你的 sql 查询中。

标签: sql sql-server sql-server-2008 sql-server-2005


【解决方案1】:

只是为了好玩和好奇你为什么想要那个:

select * 
from 
( select idx = left(names,1)
       , names
       , rn = row_number() over (partition by left(names,1) order by names) 
  from 
  ( values ('A1'),('B1'),('A2'),('C1'),('A3'),('A4'),('B2')) 
  v(names)
) dat
pivot 
( max(names)
  for idx in ([A],[B],[C],[D])
) p              

http://sqlfiddle.com/#!6/9eecb/4013/0

【讨论】:

  • 其实,我想在将names列拆分为多列后,将其作为数据集导入SSRS中,然后将每一列分配给表中的列以显示在报告中。
【解决方案2】:

我认为这不是应该在 SQL 中解决的问题。这是一个可能应该在应用程序中完成的具有代表性的事情。

但是,如果您坚持为此使用 SQL,您可以这样做。此查询的主要问题是 ROW_NUMBER 函数对性能非常不利。

WITH nameA
(
   SELECT name, ROW_NUMBER() OVER(ORDER BY name) AS rn
   FROM t1
   WHERE name LIKE 'a%'
), nameB AS
(
   SELECT name, ROW_NUMBER() OVER(ORDER BY name) AS rn
   FROM t1
   WHERE name LIKE 'b%'
)
SELECT name FROM nameA
FULL OUTER JOIN nameB
ON nameA.rn = nameB.rn
ORDER BY nameA.rn,nameB.rn;

【讨论】:

  • 这会起作用,但它会让数据库引擎跳过很多昂贵的环节,而在表示层中会更便宜(我认为回答者知道)
【解决方案3】:

您可以使用 CASE (https://msdn.microsoft.com/en-us/library/ms181765.aspx)

这个查询应该可以工作:

SELECT 
    CASE WHEN users.name like 'a%' THEN users.name  ELSE NULL END AS NameA,
    CASE WHEN users.name like 'b%' THEN users.name  ELSE NULL END AS NameB,
    CASE WHEN users.name like 'c%' THEN users.name  ELSE NULL END AS NameC,
    CASE WHEN users.name like 'd%' THEN users.name  ELSE NULL END AS NameD
FROM users

【讨论】:

  • 这是否满足原始问题尚不完全清楚。它会产生输出,其中每个名称都有一行包含大量空值。
  • 不,不会的。这将给出像 null, null, claire, null 这样的行
  • 你们俩都是对的。它给出了类似的输出,但包含很多 null
  • 我想我不能在没有 null 的情况下显示它。我可以在单独的列中计算它们吗,因为我想用它们的列名制作条形图报告
  • 当然有可能,得到你想要的结果,这不是小事。
【解决方案4】:

看看这篇文章,它非常接近你的问题。 Itzik Ben-Gan | SQL Server Pro

【讨论】:

    【解决方案5】:

    这并不是关系数据库的真正工作方式。当您在同一行中有数据时,它应该以某种方式相关 - 至少是一个通用 ID。是什么将名字恰好以 A 开头的人与名字恰好以 B 开头的人联系起来?为什么你会希望 RDBMS 建立这样的任意连接?

    如果您需要以这种方式显示用户,您只需要编写几个查询并让您的表示层处理正确的布局,例如

    SELECT name FROM users WHERE name LIKE 'a%'
    SELECT name FROM users WHERE name LIKE 'b%'
    SELECT name FROM users WHERE name LIKE 'c%'
    etc...
    

    表示层可以运行每个查询,然后适当地填充一个表。更好的是让表示层只运行这个查询:

    SELECT name FROM users
    

    然后对数据进行适当的排序和显示,这可能比 SQL Server 对用户表的多次扫描成本更低。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-13
      • 1970-01-01
      • 2018-08-31
      相关资源
      最近更新 更多