Запрос PDOStatement с подзапросами возвращает пустой результат

У меня есть следующий код PHP, который странное поведение. Система опирается на базу данных PostgreSQL, версия PHP - 5.3.15.

    $sql = "SELECT ce.id FROM calendar_events AS ce
        WHERE ce.rowid = :rowid
        AND ((SELECT count(*) FROM calendar_events_attendees AS cea WHERE cea.event_id = ce.id AND cea.status <> 'D') > 0
            OR (SELECT count(*) FROM calendar_events_globalfnbl AS ceg WHERE ceg.event_id = ce.id AND ceg.status <> 'D') > 0)";

$stmt = db_prepare($sql); // Creates a PDOStatement
$stmt->bindValue(":rowid", $rowid, PDO::PARAM_INT);
$rv = $stmt->execute();

if($rv) {
    return $stmt->fetchAll(PDO::FETCH_COLUMN, 0);
}
else {
    return null;
}

Запрос выполняется без ошибок, но функция возвращает пустой массив. Определенно, в базе данных есть строки, которые я могу найти. Если я выполню запрос в pgAdmin (местозаполнитель заменяется на идентификатор, о котором идет речь, конечно), он вернет строки, которые я хочу получить.

Мне удалось выяснить, что подзапросы являются проблемой здесь. Если я закомментирую их и использую следующий запрос, строки будут возвращены. Но, конечно, это также возвращает строки, которые я пытаюсь отфильтровать с помощью подзапросов.

$sql = "SELECT ce.id FROM calendar_events AS ce
        WHERE ce.rowid = :rowid";

PDO просто не поддерживает этот тип подзапросов или в моем коде есть ошибка, которую я не могу найти?

Заранее спасибо!

2 ответа

Решение

Это была не проблема с PDO, а с моим кодом. После двойной проверки кода, вызывающего вышеупомянутую функцию снова и снова, я нашел несколько операторов, которые устанавливают статус 'D' для рассматриваемых строк ДО того, как был выполнен вышеуказанный код.

Так что этот вопрос сейчас устарел, извините за тратить время, ребята!

Я не знаю о твоих рамках, но твоя COUNT(*) > 0 подзапросы кажутся эквивалентными EXISTS (...) подзапросы (которые также могут быть быстрее, так как они не должны считать все удовлетворяющие кортежи)

SELECT ce.id 
FROM calendar_events AS ce
WHERE ce.rowid = :rowid
AND ( EXISTS (SELECT *
                FROM calendar_events_attendees AS exa
                WHERE exa.event_id = ce.id AND exa.status <> 'D'
                )
     OR EXISTS (SELECT * 
                FROM calendar_events_globalfnbl AS exg
                WHERE exg.event_id = ce.id AND exg.status <> 'D'
                )
        );
Другие вопросы по тегам