2010-07-30 2 views
4

все с использованием MySQL знает:Есть ли аналогичная функция в postgresql для mysql SQL_CALC_FOUND_ROWS?

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

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

SELECT FOUND_ROWS(); 

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

ответ

5

Нет, нет (не менее not as of July 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; 

В isolation level должны быть SERIALIZABLE, чтобы убедиться, что запрос не видит одновременные обновлений между ЗЕЬЕСТОМ.

Другим вариантом, который у вас есть, является использование триггера для подсчета строк, так как они являются 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; 
+0

хорошо, спасибо за это! – helle

0

Нет, PostgreSQL не пытается сосчитать все соответствующие результаты, когда вам нужно только 10 результатов. Для подсчета всех результатов вам нужен отдельный COUNT.

3

Существует простой способ, но имейте в виду, что после COUNT (*) Aggr функция будет применена ко всем строкам возвращаются после того, как, где и до предела/смещения (может быть costy)

ВЫБРАТЬ идентификатор, "считать" (*) OVER() AS CNT ОТ объектов ГДЕ идентификатор> 2 OFFSET 50 LIMIT 5

Смежные вопросы