MySQL选择,加入和设置密钥作为列名 - SQL AS

时间:2014-02-14 12:58:28

标签: mysql sql

这是SQLFiddle: http://sqlfiddle.com/#!2/b2cf7/15

我想连接两个表,并选择meta_key并使其成为meta_value字段的列名。以下是我想加入的表格

表一

+----+-------------+-----------------------+
| ID | post_author |       post_date       |
+----+-------------+-----------------------+
| 20 |           1 | '2014-02-13 22:29:04' |
| 21 |           1 | '2014-02-13 22:29:04' |
| 22 |           2 | '2014-02-13 22:29:04' |
| 23 |           1 | '2014-02-13 22:29:04' |
| 24 |           2 | '2014-02-13 22:29:04' |
+----+-------------+-----------------------+

表二

+---------+---------+---------------+----------------------------------------+
| meta_id | post_id |   meta_key    |               meta_value               |
+---------+---------+---------------+----------------------------------------+
|      42 |      20 | 'user_title'  | 'My Title!'                            |
|      43 |      20 | 'user_upload' | 'true'                                 |
|      44 |      20 | 'user_desc'   | 'a description!'                       |
|      46 |      21 | 'user_title'  | 'whats that about!'                    |
|      47 |      21 | 'user_upload' | 'truth'                                |
|      48 |      21 | 'user_desc'   | 'this table runs'                      |
|      49 |      22 | 'user_title'  | 'third title, dang!'                   |
|      50 |      22 | 'user_upload' | 'true'                                 |
|      51 |      22 | 'user_desc'   | 'the desc is always true in this case' |
|      52 |      23 | 'user_title'  | 'another one'                          |
|      53 |      23 | 'user_upload' | 'true')                                |
|      54 |      23 | 'user_desc'   | 'thrilling'                            |
|      55 |      23 | 'user_title'  | 'lasty last'                           |
|      57 |      23 | 'user_upload' | 'true'                                 |
|      59 |      23 | 'user_desc'   | 'and its done'                         |
+---------+---------+---------------+----------------------------------------+

这就是我希望它如何照顾JOIN和SELECT AS

+---------+-------------+----------------------+-------------+----------------------------------------+
| post_id | post_author |      user_title      | user_upload |               user_desc                |
+---------+-------------+----------------------+-------------+----------------------------------------+
|      20 |           1 | 'My Title!'          | 'true'      | 'a description!'                       |
|      21 |           1 | 'whats that about!'  | 'truth'     | 'this table runs'                      |
|      22 |           2 | 'third title, dang!' | 'true'      | 'the desc is always true in this case' |
|      23 |           1 | 'another one'        | 'true'      | 'thrilling'                            |
|      24 |           2 | 'lasty last'         | 'true'      | 'and its done'                         |
+---------+-------------+----------------------+-------------+----------------------------------------+

2 个答案:

答案 0 :(得分:2)

解决此问题的一种方法是使用join和条件聚合:

select p.id as post_id, p.post_author,
       max(case when pm.meta_key = 'user_title' then pm.meta_value end) as user_title,
       max(case when pm.meta_key = 'user_upload' then pm.meta_value end) as user_upload,
       max(case when pm.meta_key = 'user_desc' then pm.meta_value end) as user_desc
from posts p left outer join
     postmeta pm
     on p.id = pm.post_id
group by p.id, p.post_author;

另一种方法是使用join:

select p.id as post_id, p.post_author, title.meta_value as user_title,
       upload.meta_value as user_upload, desc.meta_value as user_desc
from posts p left outer join
     postmeta title
     on p.id = title.post_id and title.meta_value = 'user_title' left outer join
     postmeta upload
     on p.id = title.post_id and title.meta_value = 'user_upload' left outer join
     postmeta desc
     on p.id = title.post_id and title.meta_value = 'user_desc';

哪个更好取决于几个因素,例如数据大小,索引以及表的大小。

编辑:

要添加where upload = 'true',您可以添加:

having user_upload = 'true'

要么查询。由于group by,这在第一个工作。它在第二个工作,因为MySQL扩展允许使用列别名在having子句中进行过滤,即使没有group by

答案 1 :(得分:1)

另一种方法,

Declare  @posts TABLE
 (
  ID bigint  primary key,
  post_author bigint not null,
  post_date datetime not null
 );

INSERT INTO @posts 
(ID, post_author, post_date) 
VALUES
  (20, 1, '2014-02-13 22:29:04'),
  (21, 1, '2014-02-13 22:28:06'),
  (22, 2, '2014-02-13 22:26:27'),
  (23, 1, '2014-02-13 22:26:08'),
  (24, 2, '2014-02-13 22:25:02');

Declare  @postmeta TABLE
(
  meta_id bigint  primary key,
  post_id bigint not null,
  meta_key varchar(255),
  meta_value varchar(255)
);

INSERT INTO @postmeta 
(meta_id, post_id, meta_key, meta_value) 
VALUES
  (42, 20, 'user_title', 'My Title!'),
  (43, 20, 'user_upload', 'true'),
  (44, 20, 'user_desc', 'a description!'),
  (46, 21, 'user_title', 'a different title'),
  (47, 21, 'user_upload', 'true'),
  (48, 21, 'user_desc', 'this table runs'),
  (49, 22, 'user_title', 'third title, dang!'),
  (50, 22, 'user_upload', 'true'),
  (51, 22, 'user_desc', 'the desc is always true in this case'),
  (52, 23, 'user_title', 'another one'),
  (53, 23, 'user_upload', 'true'),
  (54, 23, 'user_desc', 'thrilling'),
  (55, 23, 'user_title', 'lasty last'),
  (57, 23, 'user_upload', 'true'),
  (59, 23, 'user_desc', 'and its done');

  with cte as
  (select distinct p.ID ,p.post_author

  from @posts p inner join @postmeta pm on p.ID=pm.post_id
  )
  select id,post_author
  ,(select top 1  meta_value   from @postmeta pm1 where meta_key='user_title'  and c.ID=pm1.post_id order by meta_id )
   ,(select top 1  meta_value   from @postmeta pm1 where meta_key='user_upload'  and c.ID=pm1.post_id order by meta_id)
    ,(select top 1  meta_value   from @postmeta pm1 where meta_key='user_desc'  and c.ID=pm1.post_id order by meta_id  )

    from cte c