尝试通过 pg_query_params 创建和回显数组

Trying to create and echo array via pg_query_params

我使用过一些 Postgresql,但我还是个新手。我通常默认创建太多的查询并通过黑客攻击从查询中获得我需要的结果。这次我想写一些更精简的代码,因为我要处理一个大型数据库,代码需要尽可能简洁。

所以我有很多点数据,然后我有很多县。我有两个表,"counties" 和 "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 将参数传递到查询中。当我尝试在 PHP 中 运行 一个 for 循环时,我收到错误提示 "query failed: ERROR: column "jackson" does not exist",等等。这是循环:

$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 =  and time >= (NOW() - '40 DAY'::INTERVAL)";

$result = pg_query_params($conn, $query, $counties);

我收到此错误:查询失败:错误:绑定消息提供 9 个参数,但准备语句“”需要 1 个

所以我基本上想知道将参数(可能是 URL 传递的参数中的单个参数或数组中的多个元素)传递给 postgresql 查询的最佳方法是什么?然后我想以有条理的方式呼应总结结果。

感谢您对此的任何帮助。

要在多个值的循环中使用参数执行查询,您可以使用以下模式:

$counties = array('Jackson', 'Josephine', 'Curry');
$query = "SELECT countyname, time from counties where countyname = ";

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";
}

如果您只需要知道有多少点落入数组中指定的每个县,那么您可以在对数据库的一次调用中执行以下操作:

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;

这比单独调用效率高得多,而且您 return 只需一个县名实例,而不是针对检索到的每条记录一个实例。如果你在国家 Klamath 有 1,000 分,你 return 字符串 "Klamath" 只是一次,而不是 1,000 次。此外,php 不必计算查询结果的长度。总而言之,更干净、更快。

另请注意 JOIN 语法与 PostGIS 函数调用的结合。