我曾经和Postgresql合作过一些,但我还是个新手。我通常默认创建太多的查询和黑客攻击以获得我需要的查询结果。这次我想写一些更简化的代码,因为我将处理一个大型数据库,代码需要尽可能简洁。
所以我有很多点数据,然后我有很多县。我有两个表,“县”和“ltg_data”(很多点)。我的目标是通读指定数量的县(如数组中所示)并确定每个县的落点数。我这样做的新手,重复和低效的方法是编写这样的查询:
$klamath_40_days = pg_query($conn, "SELECT countyname, time from counties, ltg_data where st_contains(counties.the_geom, ltg_data.ltg_geom) and countyname");
$klamath_rows = pg_num_rows($klamath_40_days);
如果我为每个县运行如上所述的单独查询,它会给我很好的输出,但它重复且低效。我宁愿使用循环。最后我需要通过URL将params传递给查询。当我尝试在PHP中运行for循环时,我收到错误,说“查询失败:错误:列”杰克逊“不存在”,等等。这是循环:
$counties = array ('Jackson', 'Klamath');
foreach ($counties as $i) {
echo "$i<br>";
$jackson_24 = pg_query($conn, "SELECT countyname, time from counties, ltg_data where st_contains(counties.the_geom, ltg_data.ltg_geom) and countyname = ".$i." and time >= (NOW() - '40 DAY'::INTERVAL)");
$jackson_rows = pg_num_rows($result);
}
echo "$jackson_rows";
然后我研究了PHP中的pg_query_params功能,我认为这会有所帮助。但我运行这个脚本:
$counties = array('Jackson', 'Josephine', 'Curry', 'Siskiyou', 'Modoc', 'Coos', 'Douglas', 'Klamath', 'Lake');
$query = "SELECT countyname, time from counties, ltg_data where st_contains(counties.the_geom, ltg_data.ltg_geom) and countyname = $1 and time >= (NOW() - '40 DAY'::INTERVAL)";
$result = pg_query_params($conn, $query, $counties);
我收到此错误:查询失败:错误:绑定消息提供9个参数,但准备好的语句“”需要1个
所以我基本上想知道将参数传递的最佳方法(或者从URL传递param或者数组中的多个元素)到postgresql查询是什么?然后我想以有条理的方式回应总结果。
感谢您提供任何帮助。
答案 0 :(得分:1)
要在循环中为多个值执行带有参数的查询,可以使用以下模式:
$counties = array('Jackson', 'Josephine', 'Curry');
$query = "SELECT countyname, time from counties where countyname = $1";
foreach ($counties as $county) {
$result = pg_query_params($conn, $query, array($county));
$row = pg_fetch_row($result);
echo "$row[0] $row[1] \n";
}
请注意pg_query_params()
的第三个参数是一个数组,因此即使只有一个参数,也必须放array($county)
。
您还可以使用数组作为参数执行一个查询。 在这种情况下,您应该对数组使用postgres语法,并将其作为文本变量传递给查询。
$counties = "array['Jackson', 'Josephine', 'Curry']";
$query = "SELECT countyname, time from counties where countyname = any ($counties)";
echo "$query\n\n";
$result = pg_query($conn, $query);
while ($row = pg_fetch_row($result)) {
echo "$row[0] $row[1] \n";
}
答案 1 :(得分:1)
如果您只需要知道数组中指定的每个县有多少个点,那么您可以通过一次调用数据库来执行以下操作:
SELECT countyname, count(*)
FROM counties
JOIN ltg_data ON ST_contains(counties.the_geom, ltg_data.ltg_geom)
WHERE countyname = ANY ($counties)
AND time >= now() - interval '40 days'
GROUP BY countyname;
这比单独调用更有效,并且只返回县名的单个实例,而不是每个检索到的记录一个。如果你在国家克拉马斯(Klamath)有1000分,那么你就可以归还#34; Klamath&#34;只有一次,而不是1000次。此外,php
不必计算查询结果的长度。总而言之,更清洁,更快。
还要注意JOIN
语法与PostGIS函数调用的结合。