C++Builder
  Начало   Форум   Помощь Войти Регистрация  
Страниц: [1]   Вниз
  Печать  
Автор Тема: SQL запрос  (Прочитано 2602 раз)
SilverFish
Участник


Сказали спасибо: +14/-6
Offline

Сообщений: 786


SQL запрос
« : 20 Март 2015, 14:43:42 »

Как написать SQL запрос для такой ситуации:
Две одинаковые пустые таблицы.
Допустим поля у таблиц:
ids serial NOT NULL, первичный ключь
log character varying(255) NOT NULL,
set boolean NOT NULL,
serother character varying(255) NOT NULL,
vremya timestamp with time zone NOT NULL,
count integer,
address character varying(255) NOT NULL,

Теперь, когда приходят данные в таблицу №1, я делаю постоянный INSERT и идет накопление записей. Тут все нормально

Мне надо чтобы во второй таблице была одна запись, но самая свежая из первой таблицы.
Как это правильно сделать? Т.е. надо как-то организовать однократный INSERT а затем делать постоянно UPDATE.

Как определить, что записи еще во второй таблице нет вообще и сделать тогда INSERT, а если запись есть сделать ей UPDATE.
Не соображу, как это реализовать.
Если приборов два, то во второй таблице должны быть только две записи от этих приборов.
Ну а в первой все вперемешку тут все понятно.

Допустим присылают данные два прибора. Поле serother уникально для каждого прибора.
Во второй таблице тогда должно быть только две записи и постоянный их UPDATE самыми свежими записями из таблицы №1.

« Последнее редактирование: 20 Март 2015, 15:27:25 от SilverFish » Записан
gen
Участник


Сказали спасибо: +28/-0
Offline

Сообщений: 52


Re: SQL запрос
« Ответ #1 : 20 Март 2015, 15:39:20 »

Ну я конечно не владею (а из сообщения абсолютно не ясно) всеми ньюансами Вашей задачи, но зачем обязательно иметь вторую физическую таблицу. Если задача - в независимости от времени и количества входных данных, в любое момент получить самые свежие записи, то я бы воспользовался представлением, к примеру таким:
Код
    SELECT tabl1.idserial,
        tabl1.log,
        tabl1.SET,
        tabl1.serother,
        tabl1.vremya,
        tabl1.COUNT,
        tabl1.address
 FROM tabl1
 WHERE ((tabl1.serother, tabl1.vremya) =
       (
         SELECT d1.serother,
                MAX(d1.vremya) AS MAX
         FROM tabl1 d1
         WHERE d1.serother = tabl1.serother
         GROUP BY d1.serother
       ));
Записан
SilverFish
Участник


Сказали спасибо: +14/-6
Offline

Сообщений: 786


Re: SQL запрос
« Ответ #2 : 20 Март 2015, 15:45:21 »

Цитировать
но зачем обязательно иметь вторую физическую таблицу.

В первой таблице будет очень очень много записей. А вторую надо выводить в грид. Так хотят постановщики задачи.
Записан
gen
Участник


Сказали спасибо: +28/-0
Offline

Сообщений: 52


Re: SQL запрос
« Ответ #3 : 20 Март 2015, 15:54:32 »

Ну так если для показа (не для изменения), то и подцепить вышеприведенное представление к гриду. Ну если надо иметь эти данные не только для показа, но и для редактирования, то может посмотреть в сторону: прикрутить триггер на вставку к первой таблице, в триггере проверить наличие/отсутствие данных во второй таблице и вставить (или изменить) соответствующую запись.
Записан
SilverFish
Участник


Сказали спасибо: +14/-6
Offline

Сообщений: 786


Re: SQL запрос
« Ответ #4 : 20 Март 2015, 16:06:34 »

Хотят именно две таблицы.
Наверное тригер самое правильное решение. Проблема как его написать на особом языке который поддерживает база данных PostgreSQL. Понятия не имею как это пишется.
Записан
gen
Участник


Сказали спасибо: +28/-0
Offline

Сообщений: 52


Re: SQL запрос
« Ответ #5 : 20 Март 2015, 16:33:57 »

ну если в двух словах, то: пишется процедура на подобии (table1,table2  - это Ваши таблицы)  :
Код
CREATE OR REPLACE FUNCTION public.table1_tr_f (
)
RETURNS TRIGGER AS
$body$
DECLARE
 vidserial2 INTEGER;
BEGIN
--проверяем наличие во 2 таблице
BEGIN
SELECT idserial INTO vidserial2 FROM table2 WHERE serother=NEW.serother;
EXCEPTION
WHEN NO_DATA_FOUND THEN
vidserial2:=NULL;
END;
IF vidserial2>0 THEN
--есть запись - обновляем
UPDATE table2 SET log=NEW.log,SET=NEW.SET,vremya=NEW.vremya,COUNT=NEW.COUNT,address=NEW.address WHERE idserial=vidserial2;
ELSE
--нет записи - вставляем
INSERT INTO table2(log,SET,serother,vremya,COUNT,address)VALUES(NEW.log,NEW.SET,NEW.serother,NEW.vremya,NEW.COUNT,NEW.address);
END IF;  
RETURN NEW;
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;
затем к первой таблице создается триггер на вставку записи:
Код
CREATE TRIGGER temp1_tr
 AFTER INSERT
 ON public.table1 FOR EACH ROW
 EXECUTE PROCEDURE public.table1_tr_f();
который и выполняет ранее созданную процедуру автоматически при вставке каждой записи. В процедуру можно добавить все, что требуется, проверки, логику и т.д.
Записан
SilverFish
Участник


Сказали спасибо: +14/-6
Offline

Сообщений: 786


Re: SQL запрос
« Ответ #6 : 20 Март 2015, 16:51:53 »

Большое спасибо!
Сейчас буду разбираться...
Записан
SilverFish
Участник


Сказали спасибо: +14/-6
Offline

Сообщений: 786


Re: SQL запрос
« Ответ #7 : 24 Март 2015, 14:42:48 »

Все получилось, спасибо!

P.S.
Чтобы темы не плодить:
Подскажите, пожалуйста как в PostgreSQL сделать SQL запрос за последние 7 дней, включая время (00:00:00-23:59:59) по колонке timestamp without time zone? Что-то никак не получается.
Записан
gen
Участник


Сказали спасибо: +28/-0
Offline

Сообщений: 52


« Ответ #8 : 26 Март 2015, 09:50:49 »

А так:
Код
SELECT * FROM table1 WHERE 
time_field BETWEEN to_timestamp(to_char(DATE(now() - INTERVAL '7 days'),'dd.mm.yyyy'), 'dd.mm.yyyy HH24:MI:SS')
AND to_timestamp(to_char(DATE(now()),'dd.mm.yyyy') || ' 23.59.59', 'dd.mm.yyyy HH24:MI:SS')
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  




....

Powered by SMF 1.1.21 | SMF © 2025, Simple Machines
Страница сгенерирована за 0.056 секунд. Запросов: 19.