MySQL:获取具有相同数据的多行以跨越列

时间:2016-02-15 20:56:19

标签: mysql

我正在尝试制作一张表格,列出与每位客户一起为该雇主提供的所有不同的雇主和员工分配。但是他们从我们的数据库填充的方式是每个客户端的重复行,所以它看起来像这样:

id  name    staff            employer
1   Joe     Seinfeld, Jerry  Body Shop
1   Joe     Seinfeld, Jerry  Party Inc.
2   Puddy   Seinfeld, Jerry  Body Shop
3   Newman  Costanza, George Computers Inc.
3   Newman  Benes, Elaine    Postal Service
4   Delores Seinfeld, Jerry  Mulva LLC
5   Morty   Kramer, Cosmo    Executive Raincoats

正如您在第1列中的多个ID所看到的那样,Joe适用于两个地方(Body Shop和Party Inc.),因此为他填充了两行。虽然我想运行MySQL查询并让Joe(以及任何其他多个职位人员)在一行列出所有内容。类似的东西:

id  name    staff1           employer1           staff2          employer2
1   Joe     Seinfeld, Jerry  Body Shop           Seinfeld, Jerry Party Inc.
2   Puddy   Seinfeld, Jerry  Body Shop      
3   Newman  Costanza, George Computers Inc.      Benes, Elaine   Postal Service
4   Delores Seinfeld, Jerry  Mulva LLC      
5   Morty   Kramer, Cosmo    Executive Raincoats

或者以最简单的方式展示所有数据,但删除所有重复的ID并将其显示在附加到该ID的其他列中。此外,每个雇主都被分配给一名工作人员 - 并且没有两名工作人员将拥有相同的雇主(即使数据库不将其作为单独的表格导出)。

希望有道理!我还制作了一个SQLFiddle,其中包含更多示例(以及另一个将工作人员姓名与其电子邮件相匹配的表格,这是查询的另一个[不太重要]部分)。

2 个答案:

答案 0 :(得分:1)

您可以使用变量来模拟具有ROW_NUMBER子句的PARTITION BY窗口函数,这在MySQL中不可用:

SELECT ID, name,
       MAX(CASE WHEN rn = 1 THEN employer END) AS employer1,
       MAX(CASE WHEN rn = 1 THEN staff END) AS staff1,
       MAX(CASE WHEN rn = 2 THEN employer END) AS employer2,
       MAX(CASE WHEN rn = 2 THEN staff END) AS staff2
FROM (     
  SELECT ID, name, employer, staff, email,
         @rn := IF(@id = t1.ID, @rn + 1,
                  IF(@id := t1.ID, 1, 1)) AS rn
  FROM (
    SELECT t1.ID, t1.name, t1.employer, t1.staff, t2.email
    FROM table1 t1
    JOIN table2 t2 ON t1.staff = t2.staff) AS t1
  CROSS JOIN (SELECT @rn := 0, @id := 0) AS vars
  ORDER BY ID) AS t2
GROUP BY ID, name  

变量@rn枚举每个ID分区中的记录。使用@rn,我们可以应用条件聚合,以便透视原始表格的字段employerstaffemail等。

注意:以上查询处理每个2的最大ID条记录。它可以很容易地扩展,以容纳更多的ID分区。

Demo here

答案 1 :(得分:1)

鉴于您的评论为3是最大值,您可以使用conditional aggregationpivot您的搜索结果。您还需要为每个组定义row_number

以下是一个例子:

select id, name, 
    max(case when rn = 1 then staff end) as staff1,
    max(case when rn = 1 then employer end) as employer1,
    max(case when rn = 2 then staff end) as staff2,
    max(case when rn = 2 then employer end) as employer2,
    max(case when rn = 3 then staff end) as staff3,
    max(case when rn = 3 then employer end) as employer3
from (
    select *, @rn:=if(@previd=id,@rn+1,1) rn, @previd:=id
    from yourtable, (select @rn:=1, @previd:=0) t
    order by id
    ) t
group by id, name