Умышленно с запросом возвращать пустые записи через равные промежутки времени - PullRequest
0 голосов
/ 22 октября 2011

Я хочу написать запрос, который возвращает 3 результата, за которыми следуют пустые результаты, за которыми следуют следующие 3 результата и так далее. Так что, если моя база данных имела эти данные:

CREATE TABLE table (a integer, b integer, c integer, d integer);

INSERT INTO table (a,b,c,d) 
VALUES (1,2,3,4),
       (5,6,7,8),
       (9,10,11,12),
       (13,14,15,16),
       (17,18,19,20),
       (21,22,23,24),
       (25,26,37,28);

Я бы хотел, чтобы мой запрос возвратил это

1,2,3,4
5,6,7,8
9,10,11,12
 ,  ,  , 
13,14,15,16
17,18,19,20
21,22,23,24
  ,  ,  ,
25,26,27,28

Мне нужно, чтобы это работало для произвольно большого числа записей, для которых я выбрал, три из которых должны быть сгруппированы, как это.

Я использую Postgresql 8,3

Ответы [ 3 ]

3 голосов
/ 22 октября 2011

Это должно работать безупречно в PostgreSQL 8.3

SELECT a, b, c, d
FROM  (
    SELECT rn, 0 AS rk, (x[rn]).*
    FROM  (
        SELECT x, generate_series(1, array_upper(x, 1)) AS rn
        FROM  (SELECT ARRAY(SELECT tbl FROM tbl) AS x) x
    ) y

    UNION  ALL
    SELECT generate_series(3, (SELECT count(*) FROM tbl), 3), 1, (NULL::tbl).*
    ORDER  BY rn, rk
) z

Основные баллы

  • Работает для запроса, который выбирает все столбцы tbl.
  • Работает для любой стол.
  • Для выбора произвольных столбцов необходимо заменить (NULL::tbl).* соответствующим количеством столбцов NULL во втором запросе.
  • Предполагая, что NULL значения в порядке для "пустых" строк.
  • Если нет, вам придется преобразовать столбцы в text в первом и заменить '' на NULL во втором SELECT.
  • Запрос будет очень медленным с очень большими таблицами.

Если бы мне пришлось это сделать, я написал бы функцию plpgsql , которая просматривает результаты и вставляет пустые строки. Но вы упомянули, что у вас нет прямого доступа к БД ...

3 голосов
/ 22 октября 2011

Короче говоря, нет, это не простой способ сделать это, и, как правило, вы не должны пытаться. База данных связана с тем, что на самом деле ваши данные, а не как они будут отображаться. Не следует ожидать, что ваша база данных будет возвращать «фиктивные» или «лишние» данные, чтобы какой-либо последующий процесс давал желаемый результат. Генерирующий скрипт должен сделать это.

Так как вы не можете изменить процесс вниз по течению, вы могли бы (читай это со значительной степенью скептицизма и презрения) добавить такие вещи:

Select Top 3
  a, b, c, d
From 
  table
Union Select Top 1
  '', '', '', ''
From 
  table
Union Select Top 3 Skip 3
  a, b, c, d
From
  table

Пожалуйста, на самом деле не пытайтесь сделать это.

2 голосов
/ 22 октября 2011

Вы можете сделать это (по крайней мере, в DB2 - для вашей версии PostgreSQL не существует аналогичных функций).Зацикливание не требуется, хотя в этом есть небольшая хитрость ...
Обратите внимание, что хотя это работает , действительно лучше всего изменить код отображения.

Оператор требует CTE (хотя это можно переписать для использования других ссылок на таблицы) и функции OLAP (I думаю , вы можете переписать его в count() предыдущих строках подзапроса, но..).

WITH dataList (rowNum, dataColumn) as (SELECT CAST(CAST(:interval as REAL) / 
            (:interval - 1) * ROW_NUMBER() OVER(ORDER BY dataColumn) as INTEGER), 
                                              dataColumn
                                       FROM dataTable), 
     blankIncluder(rowNum, dataColumn) as (SELECT rowNum, dataColumn
                                           FROM dataList
                                           UNION ALL
                                           SELECT rowNum - 1, :blankDataColumn
                                           FROM dataList
                                           WHERE MOD(rowNum - 1, :interval) = 0
                                           AND rowNum > :interval)
SELECT *
FROM dataList
ORDER BY rowNum

В результате будет сформирован список этих элементов из таблицы данных с «пустой» строкой через каждые interval строк в соответствии с первоначальным запросом.Результирующий набор имеет только «пустые» строки между существующими строками - на концах нет «пустых» строк.

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