Вот оно: http://sqlfiddle.com/#!17/ff969/1
Вам нужно будет сделать очевидные переходы на разновидность Firebird SQL:
- Firebird не может вставить много строк одним оператором.
- Firebird использует синтаксис
select FIRST(1) .....
вместо select .... LIMIT 1
Обратите внимание, как я использую один запрос SELECT за другим, начиная с простых запросов, создавая сложные, проверяя каждый простой (что он действительно возвращает то, что мне нужно), прежде чем создавать более сложные конструкции поверх них.
Подробнее о процессе * КАК для увеличения запросов читайте здесь: https://stackoverflow.com/a/51398120/976391
Настройка схемы PostgreSQL 9.6 :
create table tab(
id /* INTeger NOT NULL AUTO_INCREMENT */ serial primary key,
ser varchar(20) not null,
Loc varchar(20) not null,
c1 integer not null,
c2 integer not null,
c3 integer not null,
c4 integer not null,
c5 integer not null,
c6 integer not null
);
insert into tab(ser,loc,c1,c2,c3,c4,c5,c6) values
('LSE4300308', 'Address 1', 0,0,0, 0,0,0),
('LHD4x22414', 'Address 2', 601,504,8, 130,0,0),
('LHD4x22414', 'Address 3', 2385,1163,54, 150,0,0),
('LSE4300308', 'Address 4', 2209,0,323, 0,0,0),
('LSE4300308', 'Address 5', 2257,0,330, 1661,926,0),
('LSE4300308', 'Address 6', 2278,0,330, 0,0,0),
('LSE4300308', 'Address 7', 2257,0,330, 1661,926,0),
('LSE4300308', 'Address 8', 2262,0,330, 1661,926,0),
('L873702373', 'Address 9', 12165,25467,1578, 2619,0,0),
('L873702373', 'Address A', 12165,25467,1578, 2619,0,0);
create index t_ser on tab(ser);
create /* descending */ index t_counters on tab(c1 desc,c2 desc,c3 desc,c4 desc,c5 desc,c6 desc);
Запрос 1 :
Select * from tab
Результаты
| id | ser | loc | c1 | c2 | c3 | c4 | c5 | c6 |
|----|------------|-----------|-------|-------|------|------|-----|----|
| 1 | LSE4300308 | Address 1 | 0 | 0 | 0 | 0 | 0 | 0 |
| 2 | LHD4x22414 | Address 2 | 601 | 504 | 8 | 130 | 0 | 0 |
| 3 | LHD4x22414 | Address 3 | 2385 | 1163 | 54 | 150 | 0 | 0 |
| 4 | LSE4300308 | Address 4 | 2209 | 0 | 323 | 0 | 0 | 0 |
| 5 | LSE4300308 | Address 5 | 2257 | 0 | 330 | 1661 | 926 | 0 |
| 6 | LSE4300308 | Address 6 | 2278 | 0 | 330 | 0 | 0 | 0 |
| 7 | LSE4300308 | Address 7 | 2257 | 0 | 330 | 1661 | 926 | 0 |
| 8 | LSE4300308 | Address 8 | 2262 | 0 | 330 | 1661 | 926 | 0 |
| 9 | L873702373 | Address 9 | 12165 | 25467 | 1578 | 2619 | 0 | 0 |
| 10 | L873702373 | Address A | 12165 | 25467 | 1578 | 2619 | 0 | 0 |
Запрос 2 :
Select distinct ser from tab
Результаты
| ser |
|------------|
| LSE4300308 |
| L873702373 |
| LHD4x22414 |
Запрос 3 :
Select /* First(10) */ * from tab
where ser = 'LSE4300308'
order by c1 desc,c2 desc,c3 desc,c4 desc,c5 desc,c6 desc
limit 10
Результаты :
| id | ser | loc | c1 | c2 | c3 | c4 | c5 | c6 |
|----|------------|-----------|------|----|-----|------|-----|----|
| 6 | LSE4300308 | Address 6 | 2278 | 0 | 330 | 0 | 0 | 0 |
| 8 | LSE4300308 | Address 8 | 2262 | 0 | 330 | 1661 | 926 | 0 |
| 5 | LSE4300308 | Address 5 | 2257 | 0 | 330 | 1661 | 926 | 0 |
| 7 | LSE4300308 | Address 7 | 2257 | 0 | 330 | 1661 | 926 | 0 |
| 4 | LSE4300308 | Address 4 | 2209 | 0 | 323 | 0 | 0 | 0 |
| 1 | LSE4300308 | Address 1 | 0 | 0 | 0 | 0 | 0 | 0 |
Запрос 4 :
Select /* First(1) */ * from tab
where ser = 'LSE4300308'
order by c1 desc,c2 desc,c3 desc,c4 desc,c5 desc,c6 desc
limit 1
Результаты
| id | ser | loc | c1 | c2 | c3 | c4 | c5 | c6 |
|----|------------|-----------|------|----|-----|----|----|----|
| 6 | LSE4300308 | Address 6 | 2278 | 0 | 330 | 0 | 0 | 0 |
Запрос 5 :
Select t1.ser,
( Select /* First(1) */ loc from tab
Where ser = t1.ser
order by c1 desc,c2 desc,c3 desc,c4 desc,c5 desc,c6 desc
Limit 1)
From (Select distinct ser from tab) as t1
Результаты
| ser | loc |
|------------|-----------|
| LSE4300308 | Address 6 |
| L873702373 | Address 9 |
| LHD4x22414 | Address 3 |
Конвертация Firebird 2.1.
Обратите внимание - если этот запрос не выполняется очень редко, вы все равно можете лучше изменить структуру базы данных. Независимо от того, что там уже есть, вы все равно можете ДОБАВИТЬ новые вспомогательные таблицы и можете добавить новые triggers
, чтобы автоматически обновлять эти новые таблицы. Например, одна дополнительная таблица «последний идентификатор для каждого серийного номера» облегчит вашу жизнь, выполняя команду update or insert
каждый раз, когда в местоположения вставляется новая строка.
create table so53371903(
id integer primary key,
ser varchar(20) not null,
Loc varchar(20) not null,
c1 integer not null,
c2 integer not null,
c3 integer not null,
c4 integer not null,
c5 integer not null,
c6 integer not null
);
insert into so53371903(id,ser,loc,c1,c2,c3,c4,c5,c6) values
(0,'LSE4300308', 'Address 1', 0,0,0, 0,0,0)
;
insert into so53371903(id,ser,loc,c1,c2,c3,c4,c5,c6) values
(1,'LHD4x22414', 'Address 2', 601,504,8, 130,0,0)
;
insert into so53371903(id,ser,loc,c1,c2,c3,c4,c5,c6) values
(2,'LHD4x22414', 'Address 3', 2385,1163,54, 150,0,0)
;
insert into so53371903(id,ser,loc,c1,c2,c3,c4,c5,c6) values
(3,'LSE4300308', 'Address 4', 2209,0,323, 0,0,0)
;
insert into so53371903(id,ser,loc,c1,c2,c3,c4,c5,c6) values
(4,'LSE4300308', 'Address 5', 2257,0,330, 1661,926,0)
;
insert into so53371903(id,ser,loc,c1,c2,c3,c4,c5,c6) values
(5,'LSE4300308', 'Address 6', 2278,0,330, 0,0,0)
;
insert into so53371903(id,ser,loc,c1,c2,c3,c4,c5,c6) values
(6,'LSE4300308', 'Address 7', 2257,0,330, 1661,926,0)
;
insert into so53371903(id,ser,loc,c1,c2,c3,c4,c5,c6) values
(7,'LSE4300308', 'Address 8', 2262,0,330, 1661,926,0)
;
insert into so53371903(id,ser,loc,c1,c2,c3,c4,c5,c6) values
(8,'L873702373', 'Address 9', 12165,25467,1578, 2619,0,0)
;
insert into so53371903(id,ser,loc,c1,c2,c3,c4,c5,c6) values
(9,'L873702373', 'Address A', 12165,25467,1578, 2619,0,0)
;
create index t_ser on so53371903(ser);
create descending index t_counters on so53371903(c1,c2,c3,c4,c5,c6);
Select * from so53371903;
Select distinct ser from so53371903;
Select first(10) * from so53371903
where ser = 'LSE4300308'
order by c1 desc,c2 desc,c3 desc,c4 desc,c5 desc,c6 desc;
Select first(1) * from so53371903
where ser = 'LSE4300308'
order by c1 desc,c2 desc,c3 desc,c4 desc,c5 desc,c6 desc;
Select t1.ser,
( Select First(1) loc from so53371903
Where ser = t1.ser
order by c1 desc,c2 desc,c3 desc,c4 desc,c5 desc,c6 desc
)
From (Select distinct ser from so53371903) as t1;
Примечание: Address 9
и Address 10
имеют одинаковые значения в счетчиках, как и Address 5
и Address 7
. Поскольку между ними нет «максимальных счетчиков» - «выигрышная» строка будет выбрана случайным образом. Возможно, сегодня будет один победитель, и выполнение одного и того же запроса через месяц или год даст в этих строках другой результат.