我昨天提出的问题已简化,但我意识到我必须报告整个故事。我必须将4个不同表中的4个数据提取到Firebird 2.5数据库中,并且以下查询有效:
SELECT PRODUZIONE_T t.CODPRODUZIONE, PRODUZIONE_T.NUMEROCOMMESSA as numeroco, ANGCLIENTIFORNITORI.RAGIONESOCIALE1, PRODUZIONE_T.DATACONSEGNA, PRODUZIONE_T.REVISIONE, ANGUTENTI.NOMINATIVO, ORDINI.T_DATA, FROM PRODUZIONE_T LEFT OUTER JOIN ORDINI_T ON PRODUZIONE_T.CODORDINE=ORDINI_T.CODORDINE INNER JOIN ANGCLIENTIFORNITORI ON ANGCLIENTIFORNITORI.CODCLIFOR=ORDINI_T.CODCLIFOR LEFT OUTER JOIN ANGUTENTI ON ANGUTENTI.IDUTENTE = PRODUZIONE_T.RESPONSABILEUC ORDER BY right(numeroco,2) DESC, left(numeroco,3) desc rows 1 to 500;
但是,由于REVISIONE列,查询返回的值是我的两倍(或更多)。如何仅选择具有最大REVISIONE值的单个NUMEROCOMMESSA的行?
在这里-http: //sqlfiddle.com/#!6/ce7cf/4
样本数据(如您在原始问题中设置的那样):
create table TAB1 ( cod integer primary key, n_order varchar(10) not null, s_date date not null, revision integer not null ); alter table tab1 add constraint UQ1 unique (n_order,revision); insert into TAB1 values ( 1, '001/18', '2018-02-01', 0 ); insert into TAB1 values ( 2, '002/18', '2018-01-31', 0 ); insert into TAB1 values ( 3, '002/18', '2018-01-30', 1 );
查询:
select * from tab1 d join ( select n_ORDER, MAX(REVISION) as REVISION FROM TAB1 Group By n_ORDER ) m on m.n_ORDER = d.n_ORDER and m.REVISION = d.REVISION
意见建议:
这是Firebird 3中引入的使用 窗口化函数的 另一种解决方案 -http: //sqlfiddle.com/#!6/ ce7cf/13
我手头没有Firebird 3,因此无法实际检查是否会有突然的不兼容性,请在家进行:-D
SELECT * FROM ( SELECT TAB1.*, ROW_NUMBER() OVER ( PARTITION BY n_order ORDER BY revision DESC ) AS rank FROM TAB1 ) d WHERE rank = 1
三种解决方案(包括Gordon的一种)中哪种更快,取决于特定的数据库-实际数据,现有索引,索引的选择性。
尽管窗口函数可以进行无联接查询,但我不确定对实数据的查询会更快,因为它可能只需要忽略cortege上的索引,而是在应用条件之前order+revision进行 全扫描rank=1。尽管第一个解决方案很可能会使用索引来获取最大值,而无需实际读取表中的每一行。
order+revision
rank=1
//sqlfiddle.com/#!18/ ce7cf / 2
WITH TMP AS ( SELECT *, MAX(revision) OVER ( PARTITION BY n_order ) as max_REV FROM TAB1 ) SELECT * FROM TMP WHERE revision = max_REV