简体   繁体   English

Select 整行与最后一条记录分组

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM