2

我正在使用 Wordpress 并尝试创建一个视图,以便更轻松地查看和分析我的度假村数据。度假村数据存储在 Wordpress 的 post_meta 表中,并在称为“度假村”的自定义帖子类型中引用。以下查询为我提供了要解析的结果集:

SELECT a.id, a.post_type, a.post_title, b.post_id, b.meta_key, b.meta_value
FROM alpinezone_postmeta b
INNER JOIN alpinezone_posts a ON a.id = b.post_id
WHERE a.post_type = "resorts" 

我想要对这个结果集做的是让我定义的集合中的每个唯一元键成为一列,然后每一行应该是一个唯一的 b.post_id(或 a.id),它对应于单个度假村的记录。

所以最终我最终得到:

post_title |   phone_num      | state         |
resort1    |   800-200-1111   | Vermont       |
resort2    |   800-200-2222   | New Hampshire |
resort 3   |   800-200-2323   | Maine         |

基本上......我在 MySQL 方面不是那么好,所以试图找出处理这个问题的最佳方法。我确实有一个我想要放入列中的所有 meta_key 的列表,其中有 36 个捕获了一系列信息。

编辑:更多细节。

当前结构- 也显示它来自哪个表

*alpinezone_posts   alpinezone_postmeta alpinezone_postmeta*
post_title          meta_key            meta_value
----------------------------------------------------------------
sugarloaf           snow_phone          888-234-2222
sugarloaf           vertical_feet       2300
sugarloaf           site_url            sugarloaf.com
wachusett           snow_phone          888-111-2222
wachusett           vertical_feet       1000
wachusett           site_url            wachusett.com

这两个表在表 alpinezone_postmeta 的 post_id 和表 alpinezone_posts 的 id 上连接。

只需要表 alpinezone_posts 中的 post_type 为 = "resorts" 的结果

我希望它在新视图中的外观

post_title  snow_phone      vertical_feet   site_url
-------------------------------------------------------
sugarloaf   888-234-2222    2300            sugarloaf.com
wachusett   888-111-2222    1000            wachusett.com
4

3 回答 3

7

您要使用的是带有“GROUP BY”的交叉表或数据透视表,如下例所示:http ://en.wikibooks.org/wiki/MySQL/Pivot_table

您需要使用除 SUM() 之外的其他字符串...例如 MAX(): http://forums.mysql.com/read.php?20,75357,75367#msg- 75367

    SELECT p.post_title AS post_title,
         MAX(IF(m.meta_key='phone_num',m.meta_value,0)) AS phone_num,
         MAX(IF(m.meta_key='state',m.meta_value,0)) AS state
    FROM alpinezone_postmeta m
    INNER JOIN alpinezone_posts p ON m.post_id = p.id
    WHERE p.post_type = 'resorts'
    GROUP BY m.post_id`
于 2012-07-26T22:02:32.273 回答
0

我知道您对每个度假村都有一个帖子,每个帖子或多或少都有一套完整的元数据。如果这是正确的,那么您可以通过以下方式构建一个查询来生成您所描述的表。它不是很优雅,但它可以在不使用其他编程语言或 Excel 的情况下工作(Excel 可能能够从 post_meta 表的导出中得到你想要的东西,但我的 Excel-fu 还不够好......)

SELECT posts.title,
    m1.meta_value as <your meta key 1>,
    m2.meta_value as <your meta key 2>,
    m3.meta_value as <your meta key 3>,
    ...
FROM alpinezone_posts
    LEFT OUTER JOIN alpinezone_postmeta AS m1 ON alpinezone_posts.id = m1.post_id,
    LEFT OUTER JOIN alpinezone_postmeta AS m2 ON alpinezone_posts.id = m2.post_id,
    LEFT OUTER JOIN alpinezone_postmeta AS m3 ON alpinezone_posts.id = m3.post_id,
    ...
WHERE 
    m1.meta_key = <your meta key 1>
    AND m2.meta_key = <your meta key 2>
    AND m3.meta_key = <your meta key 3>
    ...

使用LEFT OUTER JOIN而不是INNER JOIN确保您获得每个度假村的结果行,即使您没有每个 meta_key 的值。

如果您可以使用 PHP 并且 HTML 表格对您有帮助,您还可以循环所有帖子并使用get_post_custom()函数。

于 2012-07-25T21:07:39.430 回答
0

这是我编写的一个存储过程,它采用给定的帖子类型并透视所有相关的 postmeta 数据。您不需要知道元键,它会为您解决所有问题。

这不是最快的查询,我们仅将它用于迁移和深入研究数据,但它可以完成工作。

请注意,这会临时重置 concat 函数的最大长度,以便您可以构建大型 SQL 语句:

CREATE PROCEDURE `wp_posts_pivot`(IN post_type_filter varchar(50))
BEGIN

/* allow longer concat */
declare max_len_original INT default 0;
set max_len_original = @@group_concat_max_len;
set @@group_concat_max_len=100000;

SET @sql = NULL;
SELECT 
    GROUP_CONCAT(DISTINCT CONCAT('MAX(IF(pm.meta_key = ''',
                meta_key,
                ''', pm.meta_value, NULL)) AS `',
                meta_key,
                '`'))
INTO @sql FROM
    wp_posts p
        INNER JOIN
    wp_postmeta AS pm ON p.id = pm.post_id
WHERE
    p.post_type = post_type_filter;

SET @sql = CONCAT('SELECT p.id
                    , p.post_title
                    , ', @sql, ' 
                   FROM wp_posts p
                   LEFT JOIN wp_postmeta AS pm 
                    ON p.id = pm.post_id
                    where p.post_type=\'',post_type_filter,'\'
                   GROUP BY p.id, p.post_title');

/* reset the default concat */
set @@group_concat_max_len= max_len_original;

/*
select @sql;
*/

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;


END

然后,您可以通过一个简单的调用来调用它,例如这个,它将为每个“页面”帖子类型选择一行以及所有元值:

call wp_posts_pivot('page');
于 2022-01-25T22:18:32.630 回答