当前位置: 首页 > 面试题库 >

如何枢纽?如何将多行转换为多列的一行?

车明贤
2023-03-14
问题内容

我有两个表要合并。第一个表与客户一起使用,另一个表与产品一起使用。目前,我有22种产品,但我希望有一个灵活的数据库设计,因此与其在产品数据库中没有22列,我为每个客户为每个产品提供1行,所以如果我总体上添加或删除1种产品,我不会必须更改数据库结构。

我想有一条select语句,在这里我为每个客户端选择所有产品,并且输出应该在一行中,每个产品都有一列。

我看到了其他一些类似的问题,但这样做的目的是将所有行连接在1列中,这是我不想要的。

假设有2个客户和3个产品。

客户端

ClientId | ClientName
---------------------
 1       | Name1
 2       | Name2

餐桌产品

ProductId | ClientId | Product
-------------------------------------
 1        |   1      |  SomeproductA
 2        |   1      |  SomeproductB
 3        |   1      |  SomeproductA
 4        |   2      |  SomeproductC
 5        |   2      |  SomeproductD
 6        |   2      |  SomeproductA

输出应该是这样的:

表输出:

 ClientId | ClientName | Product1     | Product 2    | Product 3
 -------------------------------------------------------------------
     1    | Name1      | SomeproductA | SomeproductB | SomeproductA
     2    | Name2      | SomeproductC | SomeproductD | SomeproductA

从select语句应该计算每个客户的不同产品的数量(对于所有客户而言,它们始终是相同的)的角度来看,完美的解决方案也是灵活的,例如,如果我为所有客户添加或删除1个产品,不应更改选择语句。


问题答案:

MYSQL版

这是查询。联合查询使用用户定义的变量MySQL功能为每个客户组内的每个产品生成RowNumber(1,2,3,…)。外部查询使用GROUP BYCASE和CASE与内部表中的行号一起构成PIVOT表。如果需要更改产品列数,请考虑动态创建此查询并将其添加MAX(CASE WHEN p.RowNum=X THEN p.Product END) as ProductX到选择列表中。

select Clients.ClientName,
       MAX(CASE WHEN p.RowNum=1 THEN p.Product END) as Product1,
       MAX(CASE WHEN p.RowNum=2 THEN p.Product END) as Product2,
       MAX(CASE WHEN p.RowNum=3 THEN p.Product END) as Product3,
       MAX(CASE WHEN p.RowNum=4 THEN p.Product END) as Product4


FROM Clients
JOIN
(
  SELECT Products.*,
       if(@ClientId<>ClientId,@rn:=0,@rn),
       @ClientId:=ClientId,
       @rn:=@rn+1 as RowNum

  FROM Products, (Select @rn:=0,@ClientId:=0) as t
  ORDER BY ClientId,ProductID
 ) as P 
   ON Clients.ClientId=p.ClientId

GROUP BY Clients.ClientId

[SQLFiddle demo](http://sqlfiddle.com/#!2/c60f7/5)

SQL Server版本:

select Clients.ClientId,
       MAX(Clients.ClientName),
       MAX(CASE WHEN p.RowNum=1 THEN p.Product END) as Product1,
       MAX(CASE WHEN p.RowNum=2 THEN p.Product END) as Product2,
       MAX(CASE WHEN p.RowNum=3 THEN p.Product END) as Product3,
       MAX(CASE WHEN p.RowNum=4 THEN p.Product END) as Product4


FROM Clients
JOIN
(
  SELECT Products.*,
       ROW_NUMBER() OVER (PARTITION BY ClientID ORDER BY ProductID) 
         as RowNum

  FROM Products
 ) as P 
   ON Clients.ClientId=p.ClientId
GROUP BY Clients.ClientId

[SQLFiddle demo](http://sqlfiddle.com/#!6/dc654/3)



 类似资料:
  • 问题内容: 这是我的代码,非常简单的东西… 声明一些字段名称,阅读器使用CSV读取文件,并使用字段名称将文件转储为JSON格式。这是问题所在… CSV文件中的每个记录都在不同的行上。我希望JSON输出采用相同的方式。问题在于,将其全部倾倒在一条长长的巨线上。 我试过使用类似的代码,然后在该代码下面运行我的代码,该代码循环遍历每一行,但它在一行上执行整个文件,然后在另一行上遍历整个文件…一直持续到行

  • 这是我的示例数据。我想把它转换成: 我无法做到这一点。有人能解释一下我们是怎么做到的吗。

  • 问题内容: 假设我有一个元组列表,并且我想转换为多个列表。 例如,元组列表是 Python中是否有任何内置函数可以将其转换为: 这可以是一个简单的程序。但是我只是对Python中存在这种内置函数感到好奇。 问题答案: 内置功能几乎可以满足您的需求: 唯一的区别是您得到元组而不是列表。您可以使用将它们转换为列表

  • 问题内容: 我有一个查询,该查询始终返回一行且包含 许多 列。我想将其转换为2列和多行。 原始结果: 我想要的是: 这可能吗? 编辑(澄清) 我正在寻找一种自动的方法。IE浏览器,我可以传递任何只返回1行的查询结果。 问题答案: 您正在使用Oracle 11g吗?您尝试过枢轴旋转还是取消枢轴旋转? 更多信息在这里。

  • 我有一个这样的表,这个表中的所有用户只有两个特性 我想转换为

  • 问题内容: 我有一个带有列的详细信息表: user_id int 代码int 值int 我想建立一个汇总表,如下所示: user_id int valueA int valueB int 在详细信息表中,valueA对应于说代码5,而valueB对应于说代码6,所以我正在寻找类似的东西: 插入摘要(user_id,valueA,valueB)VALUES(从详细信息中选择???); 当然,问题是我