[英]Select entire row with group by on last record
I am trying to select only last from group by but failing each time.我正在尝试 select 仅从 group by 但每次都失败。
With this query:使用此查询:
SELECT
s.NABAVNACENA, s.ROBAID, MAX(d.DATUM) AS DATUM
FROM
DOKUMENT d
LEFT OUTER JOIN
STAVKA s ON s.VRDOK = d.VRDOK AND s.BRDOK = d.BRDOK
WHERE
d.VRDOK IN (0, 11, 18, 16, 22, 1, 2, 26, 29, 30)
AND d.DATUM >= '01.01.2021'
AND d.DATUM <= '31.12.2021'
AND s.ROBAID IN (39, 34)
GROUP BY
s.ROBAID, s.NABAVNACENA
I am getting these results我得到这些结果
NABAVNACENA ROBAID DATUM
---------------------------------
149 39 01.01.2021
130 39 03.01.2021
137 39 08.01.2021
847 34 02.01.2021
820 34 03.01.2021
However, the desired result is only two rows grouped by ROBAID
with max date.但是,所需的结果只是由ROBAID
和最大日期分组的两行。
In this case:在这种情况下:
137 39 08.01.2021
820 34 03.01.2021
When I exclude s.NABAVNACENA
from query it does return only these two rows, but when I include it it shows everything.当我从查询中排除s.NABAVNACENA
时,它确实只返回这两行,但是当我包含它时,它会显示所有内容。
I tried a lot of things from Stack Overflow that I lost count and now I do not know what to do.我从 Stack Overflow 尝试了很多东西,但我数不清了,现在我不知道该怎么做。
EDIT:编辑:
Here is table structure这是表结构
/* Table: STAVKA, Owner: SYSDBA */
CREATE TABLE "STAVKA"
(
"STAVKAID" INTEGER NOT NULL,
"VRDOK" SMALLINT NOT NULL,
"BRDOK" INTEGER NOT NULL,
"MAGACINID" SMALLINT NOT NULL,
"ROBAID" INTEGER NOT NULL,
"VRSTA" SMALLINT,
"NAZIV" VARCHAR(200),
"NABCENSAPOR" NUMERIC(15,4),
"FAKTURNACENA" NUMERIC(15,4),
"NABCENABT" DOUBLE PRECISION,
"TROSKOVI" NUMERIC(15,4),
"NABAVNACENA" NUMERIC(15,4) NOT NULL,
"PRODCENABP" NUMERIC(15,4) NOT NULL,
"KOREKCIJA" DOUBLE PRECISION,
"PRODAJNACENA" NUMERIC(15,2) NOT NULL,
"DEVIZNACENA" NUMERIC(15,4) NOT NULL,
"DEVPRODCENA" NUMERIC(15,4),
"KOLICINA" NUMERIC(15,3) NOT NULL,
"NIVKOL" NUMERIC(15,3) NOT NULL,
"TARIFAID" VARCHAR(3),
"IMAPOREZ" SMALLINT,
"POREZ" NUMERIC(15,2) NOT NULL,
"RABAT" NUMERIC(15,2) NOT NULL,
"MARZA" NUMERIC(15,2) NOT NULL,
"TAKSA" NUMERIC(15,4),
"AKCIZA" NUMERIC(15,2),
"PROSNAB" NUMERIC(15,4) NOT NULL,
"PRECENA" NUMERIC(15,4) NOT NULL,
"PRENAB" NUMERIC(15,4) NOT NULL,
"PROSPROD" NUMERIC(15,4) NOT NULL,
"MTID" VARCHAR(10),
"PT" CHAR(1) NOT NULL,
"ZVEZDICA" VARCHAR(6),
"TREN_STANJE" NUMERIC(15,3),
"POREZ_ULAZ" NUMERIC(15,2) NOT NULL,
"SDATUM" DATE,
"DEVNABCENA" NUMERIC(15,4),
"POREZ_IZ" NUMERIC(15,2) NOT NULL,
"X4" NUMERIC(15,3),
"Y4" NUMERIC(15,3),
"Z4" NUMERIC(15,3),
"CENAPOAJM" NUMERIC(15,2),
"KGID" INTEGER,
"SAKCIZA" NUMERIC(15,4) NOT NULL,
CONSTRAINT "STAVKAPRIMARYKEY" PRIMARY KEY ("STAVKAID")
);
I would like to export data but there are 500k rows and do not know how it would be here.我想导出数据,但有 500k 行,不知道会怎样。
So basically STAVKA
is DOCUMENT_ITEM
inside some DOCUMENT
That item holds ProductID (ROBAID)
, Price (NABAVNACENA)
and other data that are for that product in that document.所以基本上STAVKA
是某个DOCUMENT_ITEM
中的DOCUMENT
该项目包含ProductID (ROBAID)
、 Price (NABAVNACENA)
和该文档中该产品的其他数据。
So now I want to go through all STAVKA (DOCUMENT_ITEM)
and select last Price (NABAVNACENA)
for each ROBAID
.所以现在我想通过所有STAVKA (DOCUMENT_ITEM)
和 select 每个 ROBAID 的最后Price (NABAVNACENA)
来ROBAID
。
For single one I managed to do it like this:对于一个人,我设法这样做:
SELECT
t1.STAVKAID, s.ROBAID, s.NABAVNACENA
FROM
(SELECT FIRST 1 s.STAVKAID, d.DATUM
FROM DOKUMENT d
LEFT OUTER JOIN STAVKA s ON s.VRDOK = d.VRDOK AND s.BRDOK = d.BRDOK
WHERE d.VRDOK IN (0, 11, 18, 16, 22, 1, 2, 26, 29, 30)
AND d.DATUM >= '01.01.2021'
AND d.DATUM <= '31.12.2021'
AND s.ROBAID = 39
ORDER BY DATUM DESC) AS t1
LEFT OUTER JOIN
STAVKA s ON t1.STAVKAID = s.STAVKAID
It returns multiple rows, but I order them by DATUM DESC
and select first one, that way I selected last STAVKA
for that ROBAID
它返回多行,但我按DATUM DESC
和 select 第一个对它们进行排序,这样我为那个ROBAID
选择了最后一个STAVKA
Since I have 4k ROBAID
I do not want to run this query 4k times from my code but to return whole table to it由于我有 4k ROBAID
,我不想从我的代码中运行此查询 4k 次,而是将整个表返回给它
One of the really useful things in SQL is that you can nearly always replace a tablename in a from clause with a query: SQL 中真正有用的事情之一是您几乎总是可以用查询替换 from 子句中的表名:
SELECT
s.NABAVNACENA, x.ROBAID, x.DATUM
from DOKUMENT d
LEFT OUTER JOIN STAVKA s ON s.VRDOK = d.VRDOK AND s.BRDOK = d.BRDOK
inner join
(
select s.ROBAID, max(d.DATUM) DATUM
from DOKUMENT d
LEFT OUTER JOIN STAVKA s ON s.VRDOK = d.VRDOK AND s.BRDOK = d.BRDOK
WHERE
d.VRDOK IN (0, 11, 18, 16, 22, 1, 2, 26, 29, 30)
AND d.DATUM >= '01.01.2021'
AND d.DATUM <= '31.12.2021'
AND s.ROBAID IN (39, 34)
GROUP BY s.ROBAID
) x on s.Robaid = x.robaid and d.datum = x.datum
The extra inner join is the query which brings in the two rows wanted but doesn't have NABAVNACENA, and uses it to restrict the original query to those two rows.额外的内连接是引入需要但没有 NABAVNACENA 的两行的查询,并使用它将原始查询限制为这两行。
Can you just join the table onto itself?您可以将表连接到自身上吗? I would better use synthetic ID (always incrementing primary key, like AutoInc field in some databases, Generator+Trigger in FB2), but okay, let's try with dates.我最好使用合成 ID(总是递增主键,例如某些数据库中的 AutoInc 字段,FB2 中的 Generator+Trigger),但是好吧,让我们尝试使用日期。 Just... Take care that you would not have TWO or more rows with exactly the same date in one group.只是......请注意,您不会在一组中有两行或多行具有完全相同的日期。
Helping would be CTE introduced in FB 2.1: https://firebirdsql.org/refdocs/langrefupd21-select.html#langrefupd21-select-cte FB 2.1 中引入的 CTE 会有所帮助: https://firebirdsql.org/refdocs/langrefupd21-select.html#langrefupd21-select-cte
WITH DOKSTAV AS (
SELECT
s.NABAVNACENA, s.ROBAID, d.DATUM
FROM
DOKUMENT d, STAVKA s
WHERE s.VRDOK = d.VRDOK
AND s.BRDOK = d.BRDOK
)
SELECT
s1.NABAVNACENA, s1.ROBAID, s1.DATUM
FROM
DOKSTAV s1
LEFT OUTER JOIN
DOKSTAV s2
ON (s1.NABAVNACENA = s2.NABAVNACENA)
AND (s1.ROBAID = s2.ROBAID)
AND (s1.DATUM < s2.DATUM)
WHERE s2.DATUM IS NULL
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.