我在使用迭代SQL查询(我需要取消)解决问题时遇到了问题,而我正试图找出替代方法。
(另外;遗憾的是,AJAX并不适合)
鉴于我有以下位置数据表:
Country
country_id
name
State
state_id
country_id
name
City
city_id
state_id
name
现在,我正在尝试拉所有数据,但它实际上非常小( 147个城市,分为64个州,分为2个国家)但是这是永远的,因为我在迭代循环:
// this is pseudo-code, but it gets the point across
$countries = getCountries();
foreach($countries as &$country){
$country['states'] = $states = getStates($country['country_id']);
foreach($states as &$state){
$state['cities'] = getCities($state['state_id']);
}
}
我之所以这样,是因为我的最终结果集需要采用以下形式:
$countries = array(
array(
'name' => 'country_name',
'id' => 'country_id',
'states' => array(
array(
'name' => 'state_name',
'id' => 'state_id',
'cities' => array(
array(
'name' => 'city_name',
'id' => 'city_id',
),
// ... more cities
),
),
// ... more states
),
),
// ... more countries
);
我似乎无法绕过更快的方法。查询分层数据还有哪些替代方案?
修:
$sql = "SELECT
`dbc_country`.`name` as `country_name`,
`dbc_state`.`name` as `state_name`,
`city_id`,
`dbc_city`.`name` as `city_name`,
`latitude`,
`longitude`
FROM
`dbc_city`
INNER JOIN
`dbc_state` ON `dbc_city`.`state_id` = `dbc_state`.`state_id`
INNER JOIN
`dbc_country` ON `dbc_state`.`country_id` = `dbc_country`.`country_id`";
$locations = array();
foreach($datasource->fetchSet($sql) as $row){
$locations[$row['country_name']][$row['state_name']][] = array(
$row['city_id'],
$row['city_name'],
$row['latitude'],
$row['longitude'],
);
}
(我还删除了州/国家/地区的id
值,因为它们无用占用空间)
答案 0 :(得分:4)
在sql
中进行连接要快得多 然后迭代单个(更大的)结果集。
答案 1 :(得分:1)
我会使用一个查询:
SELECT co.name AS CountryName
, st.name AS StateName
, ci.name AS CityName
FROM Country AS co
LEFT JOIN State AS st
ON st.country_id = co.country_id
LEFT JOIN City AS ci
ON ci.state_id = st.state_id
ORDER BY CountryName
, StateName
, CityName
或三(如果你有很多记录,你担心从MySQL到应用程序代码的连接上发送数次"United States of America"
数次):
--- **GetCountries**
SELECT co.country_id
, co.name AS CountryName
FROM Country AS co
ORDER BY CountryName
--- **GetStates**
SELECT co.country_id
, st.state_id
, st.name AS StateName
FROM Country AS co
JOIN State AS st
ON st.country_id = co.country_id
ORDER BY CountryName
, StateName
--- **GetCities**
SELECT co.country_id
, st.state_id
, ci.city_id
, ci.name AS CityName
FROM Country AS co
JOIN State AS st
ON st.country_id = co.country_id
JOIN City AS ci
ON ci.state_id = st.state_id
ORDER BY CountryName
, StateName
, CityName
答案 2 :(得分:0)
数据库设计的常用方法强调尽可能少地进行查询。它看起来正确。但是引用这个帖子标题“查询效率”,这种方法并不适用于MySQL。仅供参考,MySQL旨在非常有效地处理连接和断开连接,并且可以非常快速地响应小而简单的查询,因此只要您立即在序列查询中释放内存,我认为没关系。此外,如果您的记录增长(例如,进入100000条记录),那么您可能会三思而后行使用JOIN语句。
答案 3 :(得分:0)
如果你的数据看起来像这样呢?
Table: country
iso_country_code country_name
--
CA Canada
US United States of America
Table: state
iso_country_code state_abbr state_name
--
US NE Nebraska
CA NB New Brunswick
Table: city
iso_country_code state_abbr city_name
--
US NE Lincoln
US NE Arapahoe
CA NB Dalhousie
CA NB Miramichi
您是否可以使用代码和缩写而不是全名?
即使您不能,也可以使用单个SELECT语句获取所有必需的行,然后遍历行以填充数组。 (您也可以使用ID号进行此操作,但使用ID号,您始终必须进行连接。使用代码和缩写,您通常只需使用代码或缩写即可满足您的用户。)