【问题标题】:Grouping cities, states and countries in MYSQL PHP在 MYSQL PHP 中对城市、州和国家进行分组
【发布时间】:2011-11-09 02:21:10
【问题描述】:

我是 PHP 新手,为此访问了几个网站,但似乎无法彻底理解。

我有这个问题:

$result = mysql_query
  ("SELECT Country, State, City
       FROM Address_Base
       ORDER BY Country, State, City")
  or die(mysql_error());

这给出了以下数据样本:

加拿大 - 州 1 - 苹果市

加拿大 - 州 2 - 城市葡萄

加拿大 - 州 1 - 苹果市

加拿大 - 州 2 - 城市咖啡

美国 - 州 1 - 城市斑马

美国 - 州 2 - 城市猫

美国 - 州 2 - 狮城

美国 - 州 3 - 城市鸟

美国 - 州 1 - 城市斑马

我的目标是将城市分组在各自的州和计数城市下,将州分组在各自的国家和相似的国家,并产生类似的东西

Canada -
{
  State 1 - City Apple (2)
  State 2 - City Coffee (1), City Grapes (1)
}

USA -
{
    State 1 - City Zebra (2)
    State 2 - City Cat (1), City Lion (1)
    State 3 - City Bird (1)
}

从其他网站,我得到了这个:

$combinedResults = array();

while ($rec=mysql_fetch_assoc($result))
{
    $combinedResults[$rec['Country']][] = array
            (               
                'S' => $rec['State'], 
                'C' => $rec['City']
            );                           
}

foreach(array_keys($combinedResults) as $Country)
{ 
    echo '<div class="country">'.$Country.'</div>';

    foreach($combinedResults[$Country] as $Set)
    { 
        echo $Set['S'].'<br/>'.$Set['C'].'<br/><br/>'; 
    } 
} 

这只会对类似的国家/地区进行分组,而不是对州和城市进行分组。我猜上面的代码正在尝试对某种多维数组中的数据进行预处理,并让 for 循环显示结果。看不懂。

如果有人可以为我解释一下,我将非常感激,我可以如何按照上面的要求分别对州和城市进行进一步分组?

【问题讨论】:

    标签: php mysql multidimensional-array group-by


    【解决方案1】:
    $result = mysql_query('SELECT Country, State, City From Address_Base ORDER BY Country, State, City') or die(mysql_error());
    
    $countries = array();
    
    // fetch results and build multidimensional array of city counts
    while($row = mysql_fetch_array($result, MYSQL_ASSOC)){
        if(isset($countries[$row['Country']][$row['State']][$row['City']])){
            $countries[$row['Country']][$row['State']][$row['City']] += 1;
        } else{
            $countries[$row['Country']][$row['State']][$row['City']] = 1;
        }
    }
    
    // loop over all countries
    foreach($countries as $country => $states){
        echo $country, PHP_EOL, '{'; // output country start
    
        // loop over all states
        foreach($states as $state => $cities){
            echo $state, ' - '; // output state start
    
            $cityCounts = array();
            foreach($cities as $city => $count){
                $cityCounts[] = $city.' ('.$count.')'; // add all city counts to array
            }
    
            // implode all city counts and output it
            echo implode(', ', $cityCounts);
    
            // output new line
            echo PHP_EOL;
        }
    
        // output country end
        echo PHP_EOL, '}';
    }
    

    【讨论】:

    • @Shef..... 请您详细说明这一行:$countries[$row['Country']][$row['State']][$row['City' ]] += 1 --
    • @Tede:它为城市设立了一个柜台。如果带有城市名称的数组索引存在,它将计数器加一,否则计数器将从 1 开始。
    • Shef...感谢您的回复...当我使用此行时:$countries[$row['Country']][$row['State']][$row['City ']] += 1 ...它给了我一个错误:'未定义的索引'。删除增量 '+' ,我能够实现我所针对的所有目标,除了一个州的相同城市的数量。我发现有趣的另一件事是您为创建动态多维数组进行编码的方式。我很高兴看到它,但我无法理解它。我在网上搜索了很多,但没有太多。我参考的是哪本书,或者你会找时间为我解释一下吗?
    • @Tede: Undefined index 不是错误,只是警告,忽略它。我根据您的数据库的列构建了多维数组。你可以阅读arrays on php.net docs。或者你可以谷歌它。如果有一行代码对你来说难以理解,请告诉我。
    • 我已经阅读了有关数组的内容,并且我知道我们使用 '=>' 来定义键和值...但是当我们使用这行代码时... $countries[$row[ '国家']][$row['State']][$row['City']] += 1;我觉得很难理解,这就是为什么我问....你能解释一下这条线吗?
    【解决方案2】:

    SQL 查询将为您提供一组具有固定列数的结果。您的示例具有可变数量的列(多个城市计数),因此这不起作用。

    您可以在 SQL 中使用 COUNT 和 GROUP BY 来获得类似的东西

    Country   State    Citiescount
    Canada    state1      4
    Canada    state2      3
    USA       state2      2
    

    等,但您将在左侧列中有重复项。

      SELECT country, state, COUNT(cities)
        FROM address_base
    GROUP BY country, state
    

    为了摆脱重复,循环它以创建一个多维数组,执行类似的操作

    $countries = array();
    foreach ($results as $row) {
        if (!isset($countries[$row->country])) {
            $countries[$row->country] = array();
        }
        $countries[$row->country][$row->state] = $row->citiescount;
    }
    

    或者,您可以直接回显这些内容。您可以像这样一次性获得所有结果并循环遍历整个集合,或者您可以将其分解为较小的查询并每个国家或每个州执行一个。但是请注意,将 SQL 置于循环中会杀死小猫(和数据库性能):)。

    【讨论】:

    • @Matt...我尝试过 group by ...因为它与聚合函数一起使用...对于实现我的目标显示没有太大帮助。此外,美国的两个城市可以有相同的名称但不同的州......,我尝试了按邮政编码分组......但我发现美国的邮政编码在墨西哥可以是相同的。这给我带来了一个问题。因此我放弃了那条路线。
    • GROUP BY 应该不会导致重复值的问题,只要您以正确的顺序获取子句并包含所有子句。在上面的示例中,我将国家放在首位,因此您将按国家/地区分组,然后按国家/地区中的州(每个州占一行,即使名称相同,只要它们位于不同的国家/地区)。不过,我对您最终计算的内容感到有些困惑。城市名称后括号中的数字是什么意思?
    • 城市名称后面括号中的数字给出了该州列出的同一城市的总数。例如:- 在上面的示例城市中,“苹果”在同一个城市下出现两次,所以- (2)。这是我数数。
    猜你喜欢
    • 2017-10-20
    • 2011-01-14
    • 1970-01-01
    • 1970-01-01
    • 2014-09-08
    • 1970-01-01
    • 1970-01-01
    • 2017-11-11
    • 1970-01-01
    相关资源
    最近更新 更多