我目前正在根据我在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脚本来做这件事,但是我讨厌两次点击数据库。
答案 0 :(得分:1)
首先,我认为在你正在使用的同一个循环中完成这个任务是不可能的,因为它会搞乱循环的逻辑。基本上,您只在处理一个(当前)行时尝试处理所有结果行。所以我甚至懒得看这种可能性。
相反,在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);
}
希望这会有所帮助。
答案 1 :(得分:0)
使用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"
然后您可以在&#34; ID&#34;如果是ids那么列表。
$ids = explode($row->ids, ",")
答案 2 :(得分:0)
我已修改您的代码以重复使用相同的$ 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是您需要的最终数组。做任何你想做的事。
答案 3 :(得分:0)
您需要做的就是遍历查询中的结果两次。但是,您不需要两次调用查询。首先将结果引用到变量。
然后第一次预测结果只是为了进行计数。然后执行原始foreach,并使用工具提示中的计数值。
如下所示,我在一个单独的数组中进行了计数,该数组包含每个国家/性别组合的计数。
// 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);