我目前正在根据我在wordpress中从数据库中导出的一些json数据构建一个rapheal.js映射。 我在构建 JSON 方面得到了一些帮助,但我在需要计算的一些元素方面遇到了麻烦。
如果您查看下面的脚本,您会注意到 2 行是性别和国家/地区。 性别行可以是男性、女性或其他。 这个国家显然是国家。 我正在尝试做的是计算每个国家/地区每种性别的数量,然后将其显示在工具提示数组 HTML 中。 这意味着它需要首先检查国家,然后检查每个性别中有多少属于该国家。
function mapInfo() {
global $wpdb;
$preJSON = array();
// select only columns you need
$sql = "SELECT * FROM wp_mas";
//$count = 0; // this is for $preJSON[] index
foreach( $wpdb->get_results( $sql ) as $key => $row ) {
$value = $row->id;
$latitude = $row->lat;
$longitude = $row->long;
$gender = $row->gender;
$country = $row->country_srt;
$tooltip = array(
"content" => '<h2 class="country-name">- '. $country .' -</h2><p>female amount, male amount, other amount'
);
$main = array(
"latitude" => $latitude,
"longitude" => $longitude,
"tooltip" => $tooltip
);
$preJSON[$country.$count] = array(
"latitude" => $latitude,
"longitude" => $longitude,
"tooltip" => $tooltip
);
++$count;
}
wp_send_json($preJSON);
}
我想我可以用SQL脚本来做到这一点,但我不想两次访问数据库。
首先,我认为不可能在您使用的同一循环中完成此任务,因为它会弄乱循环的逻辑。基本上,您尝试处理所有结果行,同时只处理一个(当前)行。所以我甚至懒得去看这种可能性。
相反,在sql中,仅使用一个查询是相当可行的。我现在不知道数据库中到底有什么数据,但我认为它是这样的。
id lat lng gen country
1 1 2 f USA
2 2 2 f USA
3 3 2 o FRA
5 4 3 m FRA
7 5 5 m USA
9 1 2 f USA
10 2 2 o USA
11 3 2 m FRA
12 4 3 f FRA
13 5 5 o USA
15 3 2 m FRA
16 4 3 f FRA
17 5 5 m USA
此查询将按原样获取表,并将连续连接与国家/地区匹配的每一行的行总数,其中包含 fem、mal 和 oth。
SELECT
w.id as 'id',
w.lat as lat,
w.lng as lng,
w.gen as gen,
w.country as cntry,
c.count1 as cnt_fem,
c.count2 as cnt_mal,
c.count3 as cnt_oth
FROM wp_mas as w
LEFT OUTER JOIN
(SELECT
wp_mas.country as cntry1,
wp_mas.gen as gen1,
COUNT(case wp_mas.gen when 'Female' then 1 else NULL end) as count1,
COUNT(case wp_mas.gen when 'Male' then 1 else NULL end) as count2,
COUNT(case wp_mas.gen when 'Other' then 1 else NULL end) as count3
FROM
wp_mas
GROUP BY cntry1)
as c
ON w.country=c.cntry1
也许,查询不是很优雅,但它有效。结果将是:
id lat lng gen cntry cnt_fem cnt_mal cnt_oth
1 1 2 f USA 3 2 2
2 2 2 f USA 3 2 2
3 3 2 o FRA 2 3 1
5 4 3 m FRA 2 3 1
7 5 5 m USA 3 2 2
9 1 2 f USA 3 2 2
10 2 2 o USA 3 2 2
11 3 2 m FRA 2 3 1
12 4 3 f FRA 2 3 1
13 5 5 o USA 3 2 2
15 3 2 m FRA 2 3 1
16 4 3 f FRA 2 3 1
17 5 5 m USA 3 2 2
每行将包含 3 列,其中女性、男性和其他与该行中的国家/地区匹配的总数。所以现在你可以使用你正在使用的相同循环:
foreach( $wpdb->get_results( $sql ) as $key => $row ) {
$value = $row->id;
$latitude = $row->lat;
$longitude = $row->lng;
$gender = $row->gen;
$country = $row->cntry;
$cnt_fem = $row->cnt_fem;
$cnt_mal = $row->cnt_mal;
$cnt_oth = $row->cnt_oth;
$tooltip = array(
"content" => '<h2 class="country-name">- '. $country .' -</h2><p>'.$cnt_fem.' females, '.$cnt_mal.' males, '.$cnt_oth.' other'
);
$preJSON[$country.$count] = array(
"latitude" => $latitude,
"longitude" => $longitude,
"tooltip" => $tooltip
);
++$count;
}
wp_send_json($preJSON);
}
希望这会有所帮助。
使用 GROUP sql,您应该能够获得所需的内容。
group by gender, country
这会将结果集更改为每个组的分组。
select count(*) as num_of_matches, gender, country, group_concat("id") as ids from wp_mas group by gender, country
会给你类似的东西
3, "male", "canada", "4,6,7"
然后,如果 IDS,您可以在列表的"IDS"上爆炸。
$ids = explode($row->ids, ",")
我已经修改了您的代码以重复使用相同的$sql以获取每个国家/地区不同性别的数量。您应该尝试一下,看看它是否有效。
$all_countries=array();
foreach( $wpdb->get_results( $sql ) as $key => $row ) {
$value = $row->id;
$latitude = $row->lat;
$longitude = $row->long;
$gender = $row->gender;
$country = $row->country_srt;
if(!isset($all_countries[$country][$gender])) $all_countries[$country][$gender] = array();
array_push($all_countries[$country][$gender],array("value"=>$value,"latitude"=>$latitude,"longitude"=>$longitude));
}
$main=array();
foreach($all_countries as $country => $data){
$tooltip = array("content" => '<h2 class="country-name">- '. $country .' -</h2><p>'.count($data['female']).', '.count($data['male']).', '.count($data['other']).'</p>');
$gender='';
if(count($data['male'])>0) $gender='male'; else if(count($data['female'])>0) $gender='female'; else $gender='other';
array_push($main,array(
"latitude" => $data[$gender][0]['latitude'],
"longitude" => $data[$gender][0]['longitude'],
"tooltip" => $tooltip
));
}
// Now you can do whatever you want with $main. echo its content as JSON or return, its upto you
$main是您需要的最终阵列。用它做任何你想做的事。
您需要做的就是遍历查询的结果两次。不过,您不需要调用查询两次。只需先将结果引用到变量即可。
然后第一次对结果进行计数。稍后执行原始操作,并使用工具提示中的计数值。
正如您在下面看到的,我在一个单独的数组中进行计数,该数组保存每个国家/性别组合的计数。
// select only columns you need
$sql = "SELECT * FROM wp_mas";
$result = $wpdb->get_results( $sql );
$count = 0;
foreach( $result as $row ) {
if (!isset($count[$row->gender][$row->country_srt])) {
$counters[$row->gender][$row->country_srt] = 0;
}
$counters[$row->gender][$row->country_srt] ++;
}
foreach( $result as $key => $row ) {
$value = $row->id;
$latitude = $row->lat;
$longitude = $row->long;
$gender = $row->gender;
$country = $row->country_srt;
$females = $counters['female'][$country];
$males = $counters['male'][$country];
$others = $counters['other'][$country];
$tooltip = array(
"content" => "<h2 class='country-name'>- $country -</h2><p>female $females, male $males, other $others"
);
$main = array(
"latitude" => $latitude,
"longitude" => $longitude,
"tooltip" => $tooltip
);
$preJSON[$country . $count] = array(
"latitude" => $latitude,
"longitude" => $longitude,
"tooltip" => $tooltip
);
++$count;
}
wp_send_json($preJSON);
但是您可以通过省略未使用的变量并内联引用来压缩此代码:
$sql = "SELECT * FROM wp_mas"; // select only columns you need
$result = $wpdb->get_results( $sql );
$count = 0;
foreach( $result as $row )
$counters[$row->gender][$row->country_srt] = isset($counters[$row->gender][$row->country_srt]) ? $counters[$row->gender][$row->country_srt] + 1 : 1;
foreach( $result as $key => $row )
$preJSON[$row->country_srt . ++$count] = array(
"latitude" => $row->lat,
"longitude" => $row->long,
"tooltip" => array(
"content" => "<h2 class='country-name'>- {$row->country_srt} -</h2><p>female {$counters['female'][$row->country_srt]}, male {$counters['male'][$row->country_srt]}, other {$counters['other'][$row->country_srt]}"
)
);
wp_send_json($preJSON);