2015-07-02 4 views
2

Я работал с Postgresql, но я все еще новичок. Обычно я по умолчанию создаю слишком много запросов и взламываю свой путь, чтобы получить результат, который мне нужен из запроса. На этот раз я бы хотел написать еще более упорядоченный код, так как я буду иметь дело с большой базой данных, и код должен быть как можно более кратким.Попытка создания и эхо-массива через pg_query_params

Итак, у меня много точечных данных, и тогда у меня много графств. У меня есть две таблицы: «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, я получаю сообщение об ошибке сказав «запрос не удалось: ОШИБКА: колонка„джексон“не существует», и т.д. Вот петля:

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

Итак, я исследовал особенность в pg_query_params в PHP, и я думал, что это поможет. Но я запускаю этот скрипт:

$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? И тогда я хотел бы откликнуться на итоговые результаты организованным образом.

Спасибо за любую помощь в этом.

ответ

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; 

Это намного больше эффективнее, чем отдельные вызовы, и вы возвращаете только один экземпляр имени графства, а не один для каждой записи, которая извлекается. Если у вас есть, скажем, 1000 очков в стране Klamath, вы возвращаете строку «Кламат» только один раз, а не 1000 раз. Кроме того, php не должен рассчитывать длину результата запроса. Все это намного чище и быстрее.

Обратите внимание также на синтаксис JOIN в сочетании с вызовом функции PostGIS.

+0

Это замечательно ... спасибо! Тем не менее, мне нелегко повторять результат.Я использую pg_query с $ result = pg_query ($ conn, $ query); и используя оператор while while ($ row = pg_fetch_row ($ result)) {echo "$ row [0] $ row [1] \ n"; } Он не работает и не дает никаких ошибок. Я здесь что-то не так? – user1610717

+0

Извините за это ... пропустил точку с запятой в конце инструкции запроса. Все еще некоторые ошибки, но работающие над ним. – user1610717

+0

Ах, правильно. Также проверьте для '! $ Result', чтобы проверить, нет ли ошибки DB. В противном случае выражение 'while' выглядит хорошо. – Patrick

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"; 
} 
Смежные вопросы