如何计算某个meta_key在列中出现的meta_value的次数?
Posted
技术标签:
【中文标题】如何计算某个meta_key在列中出现的meta_value的次数?【英文标题】:How to count how many times a meta_value appears in a column by certain meta_key? 【发布时间】:2016-01-20 06:07:59 【问题描述】:我正在尝试从 WordPress 的数据库中查询每条记录在我的表中的列上存在多少次并导出该列。我该怎么做?
在导出的 excel 中,我希望 meta_value 中的列带有 meta_key “user_valid”,以及一列中包含该 meta_value 在 mysql 列中存在多少次的计数。
meta_key meta_value
user_valid '1, 2, 3'
user_valid '1, 2, 1'
user_valid '1, 2, 3'
用于导出列 'meta_value' 和我使用的 meta_key 'user_valid':
SELECT meta_value FROM `us_test` WHERE meta_key = 'user_valid'
使用此查询后,我使用 MYSQL 中的导出按钮导出。
我不知道如何查询另一列。
我认为应该是这样的,但我不确定,因为当我使用下一个查询时,它不会返回所有记录:
SELECT meta_value, COUNT( * ) c FROM `us_test` WHERE meta_key = 'user_valid' GROUP BY meta_value
【问题讨论】:
我很困惑......你是否给自己一个“模范”答案的赏金?还是您正在寻找替代方案? @rnevius 我认为 OP 选择了错误的赏金解释。有更好的方法可以做到这一点,所以我认为他需要这些替代方案的答案 【参考方案1】:这里有两种选择,一种是 Wordpress,另一种是 SQL。
在我开始之前,您永远不应该对数据库名称进行硬编码,问题是,如果您将代码移动到具有不同数据库名称的另一个网站,则需要在所有硬编码查询中更改数据库名称,当您在您正在处理的网站上更改数据库名称时。如果您忘记了这一点,这会让您大吃一惊
您应该始终清理和验证输入数据,以确保可以安全地防止任何恶意代码注入您的网站。 SQL 注入很常见,许多黑客使用 SQL 注入来入侵网站
SQL
SQL 提供的控制较少,因为它的动态性较低。例如,如果您只需要获取某个词的计数,则需要直接更改查询,或者您需要实现某种过滤系统。
正如我所说,永远不要硬编码数据库名称,而是使用 wpdb 类来设置前缀。这将避免未来的问题。另外,正如我所说,您必须进行清理以避免 SQL 注入,在这种情况下,我们将使用 wpdb 类的 prepare
方法来进行清理并防止 SQL 注入。
这里是函数,我在这里和那里评论过它是有意义的:
function get_post_meta_key_count( $key = '', $value = '', $type = 'post', $status = 'publish' )
// Use $wpdb to avoid bugs and errors, do not hardcode db names
global $wpdb;
if( empty( $key ) )
return;
// Set the default WHERE clause where we return the count of the key regardless of value
$where = $wpdb->prepare(
"
pm.meta_key = '%s'
AND p.post_type = '%s'
AND p.post_status = '%s'
",
$key,
$type,
$status
);
// If a value is specified, add that to the WHERE clause
if ( $value )
$where .= $wpdb->prepare(
"
AND pm.meta_value = '%s'
",
$value
);
// Query the db to return the post count according to key and value if value is set
$count = $wpdb->get_var(
"
SELECT count(DISTINCT pm.post_id)
FROM $wpdb->postmeta pm
JOIN $wpdb->posts p ON (p.ID = pm.post_id)
WHERE $where
"
);
return $count;
我在这里所做的是,如果您需要获取特定元键的特定元值的计数,我已经设置了一个参数。
用法
您现在可以使用如下功能:
echo get_post_meta_key_count( 'my_key' );
用于 meta_key
的帖子计数 my_key
用于默认帖子类型 post
并且仅发布帖子
echo get_post_meta_key_count( 'my_key', '', 'custom_post_type', 'trash' );
用于 meta_key
的帖子计数 my_key
用于自定义帖子类型 custom_post_type
并且仅垃圾帖子
echo get_post_meta_key_count( 'my_key', 'my_value' );
用于meta_key
my_key
的帖子计数和meta_value
、my_value
用于默认帖子类型post
并且仅发布帖子
WP_Query
如果您正在寻找一种内置方式来执行此操作(这应该始终是您的首选),您可以使用 WP_Query
类来执行此操作。
使用WP_Query
的问题在于,如果使用不当,可能会非常昂贵。许多人因此而避免WP_Query
,或者在不知不觉中运行非常昂贵且不必要的查询。因此,我们将寻找一种方法使其与自定义 SQL 查询一样快。
WP_Query
上述自定义 SQL 查询的真正优势在于,您可以通过简单地传入所需的参数来调整查询,WP_Query
将始终负责根据传递参数。
让我们看看优化 WP_Query
以便只返回帖子计数
首先,我们将只查询一个帖子。 WP_Query
,默认情况下,无论查询多少帖子(1、100 或所有帖子),WP_Query
都会继续寻找所有与查询匹配的帖子,即使它已经找到并返回了查询的帖子数量。原因是分页。为了正确计算分页,WP_Query
需要知道有多少帖子与查询匹配。
所以WP_Query
在返回查询的帖子数量后继续查看数据库,以计算与查询匹配的所有帖子。这个帖子计数存储在查询的$found_posts
属性中,并且正是这个数字与posts_per_page
一起使用,用于计算将有多少页。
这不适用于get_posts
,尽管get_posts
使用WP_Query
。 get_posts
将 'no_found_rows' => true
传递给 WP_Query
,一旦找到查询的帖子数量,就会中断查询。这在法律上破坏了分页,这就是为什么 get_posts
正确分页是如此令人头疼的原因
其次,我们只会查询我们需要查询的单个帖子的ID,而不是完整的WP_Post
对象。这节省了查询时间。
让我们看看这个函数:
function get_post_meta_key_count( $key = '', $value = '', $args = [] )
// If the $key value is empty, bail
if( empty( $key ) )
return;
// Set the defaults and override any value set for the specific default
$args['posts_per_page'] = 1;
$args['fields'] = 'ids';
if ( $value )
$args['meta_query'][] = [
'key' => $key,
'value' => $value
];
else
$args['meta_query'][] = [
'key' => $key,
];
$q = new WP_Query( $args );
// Return the post count
return $q->found_posts;
用法
WP_Query
,默认使用post
帖子类型和publish
作为帖子状态,所以我们不需要为正常发布的帖子设置这个。我在这里包含了第三个参数$args
,该参数接受与WP_Query
类相同的参数,因为这些参数都直接传递给WP_Query
。因此,您可以在此处添加任何参数以从特定元键或值中获取计数
echo get_post_meta_key_count( 'my_key' );
用于meta_key
的帖子计数my_key
用于默认帖子类型post
并且仅发布帖子
echo get_post_meta_key_count( 'my_key', 'my_value' );
用于meta_key
my_key
的帖子计数和meta_value
,my_value
用于默认帖子类型post
并且仅发布帖子
echo get_post_meta_key_count( 'my_key', 'my_value', ['post_type'=>'cpt', 'cat'=>1] );
用于meta_key
my_key
的帖子计数和meta_value
、my_value
用于自定义帖子类型cpt
并且仅发布来自类别ID 1
的帖子
meta_key
的性能测试,包含 24 个帖子
SQL -> 1 个查询在 +/- 0.005 秒内
WP_Query
-> +/- 0.012 秒内 2 次查询
如您所见,性能存在细微差别,因此WP_Query
方法很容易成为最佳选择,因为它更具动态性,尽管速度稍慢
【讨论】:
【参考方案2】:所以,我会回答我自己的问题:
我的问题是绝对正确的:
SELECT meta_value, COUNT( * ) c FROM `us_test` WHERE meta_key = 'user_valid' GROUP BY meta_value
【讨论】:
以上是关于如何计算某个meta_key在列中出现的meta_value的次数?的主要内容,如果未能解决你的问题,请参考以下文章
如何计算某些值在 SQL 表中出现的次数并在列中返回该数字?
计算 PySpark SQL Join 中每个不同值在列中出现的次数