Есть ли подобная функция в postgresql для SQL_CALC_FOUND_ROWS mysql? - PullRequest
4 голосов
/ 30 июля 2010

каждый, кто использует mysql, знает:

SELECT SQL_CALC_FOUND_ROWS ..... FROM table WHERE ...  LIMIT 5, 10;

и сразу после запуска это:

SELECT FOUND_ROWS();

как мне это сделать в postrgesql? до сих пор я нашел только способы, с помощью которых я должен отправить запрос дважды ...

Ответы [ 3 ]

5 голосов
/ 30 июля 2010

Нет, нет (по крайней мере не по состоянию на июль 2007 года ).Боюсь, вам придется прибегнуть к:

BEGIN ISOLATION LEVEL SERIALIZABLE;

SELECT id, username, title, date FROM posts ORDER BY date DESC LIMIT 20;
SELECT count(id, username, title, date) AS total FROM posts;

END;

Уровень изоляции должен быть SERIALIZABLE, чтобы запрос не видел одновременных обновлений между операторами SELECT.

Другой вариант, который у вас есть, - использовать триггер для подсчета строк, когда они INSERT ed или DELETE d.Предположим, у вас есть следующая таблица:

CREATE TABLE posts (
    id      SERIAL PRIMARY KEY,
    poster  TEXT,
    title   TEXT,
    time    TIMESTAMPTZ DEFAULT now()
);

INSERT INTO posts (poster, title) VALUES ('Alice',   'Post 1');
INSERT INTO posts (poster, title) VALUES ('Bob',     'Post 2');
INSERT INTO posts (poster, title) VALUES ('Charlie', 'Post 3');

Затем выполните следующее, чтобы создать таблицу с именем post_count, которая содержит счетчик количества строк в posts:

-- Don't let any new posts be added while we're setting up the counter.
BEGIN;
LOCK TABLE posts;

-- Create and initialize our post_count table.
SELECT count(*) INTO TABLE post_count FROM posts;

-- Create the trigger function.
CREATE FUNCTION post_added_or_removed() RETURNS TRIGGER AS $$
    BEGIN
        IF TG_OP = 'DELETE' THEN
            UPDATE post_count SET count = count - 1;
        ELSIF TG_OP = 'INSERT' THEN
            UPDATE post_count SET count = count + 1;
        END IF;
        RETURN NULL;
    END;
$$ LANGUAGE plpgsql;

-- Call the trigger function any time a row is inserted.
CREATE TRIGGER post_added_or_removed_tgr
    AFTER INSERT OR DELETE
    ON posts
    FOR EACH ROW
    EXECUTE PROCEDURE post_added_or_removed();

COMMIT;

Обратите внимание, что при этом сохраняется текущий счет всех строк в posts.Чтобы сохранить счетчик определенных строк, вам нужно настроить его:

SELECT count(*) INTO TABLE post_count FROM posts WHERE poster <> 'Bob';

CREATE FUNCTION post_added_or_removed() RETURNS TRIGGER AS $$
    BEGIN
        -- The IF statements are nested because OR does not short circuit.
        IF TG_OP = 'DELETE' THEN
            IF OLD.poster <> 'Bob' THEN
                UPDATE post_count SET count = count - 1;
            END IF;
        ELSIF TG_OP = 'INSERT' THEN
            IF NEW.poster <> 'Bob' THEN
                UPDATE post_count SET count = count + 1;
            END IF;
        END IF;
        RETURN NULL;
    END;
$$ LANGUAGE plpgsql;
4 голосов
/ 20 декабря 2012

Существует простой способ, но имейте в виду, что следующая функция aggr COUNT (*) будет применена ко всем строкам, возвращаемым после, где и до предела / смещения (может быть дорогим)"count" (*) OVER () AS cnt ОТ объектов WHERE ID> 2 OFFSET 50 LIMIT 5

0 голосов
/ 30 июля 2010

Нет, PostgreSQL не пытается подсчитать все релевантные результаты, когда вам нужно только 10 результатов. Вам нужен отдельный СЧЕТ для подсчета всех результатов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...