如何 "fetch first 1 row only" 每个 ID 在 3 个不同的列中?

How to "fetch first 1 row only" per IDs in 3 different columns?

我正在尝试仅根据另外 3 列中的一组唯一 ID 获取 1 行。在我的数据库中,对于其他 3 列中的每个唯一 ID 集,每个日期 有许多 记录(例如,您可以想象产品编号)。库存状态仅按日期(更改)发布,而不是作为数量的一个最终数字。因此,获取实际库存状态的唯一方法是使用最新日期检查最新的库存状态更新 - 最上面的行总是根据给定的产品 ID 组合。

这就是我的 table 目前的样子:

Code1         Cde2         Code3           Date        Stock status
arti-cd-base  arti-cd-sfx  adfc-cd-diffco  stof-dt     stof-qty-op
------------  -----------  --------------  ----------  -----------
      1            15            0         2019-08-31       200
      1            15            0         2019-08-25       290
      2            16            2         2019-08-28       100
      2            16            2         2019-08-26        80
      2            16            2         2019-08-21       200
      3            18           25         2019-08-18        75

这就是我希望的样子 - 对于每个 arti-cd-base、arti 的组合,仅显示具有最新日期 (stpf-dt) 和库存状态 (stof-qty-op) 的行-cd-sfx 和 adfc-cd-diffco。

Code1         Cde2         Code3           Date        Stock status
arti-cd-base  arti-cd-sfx  adfc-cd-diffco  stof-dt     stof-qty-op
------------  -----------  --------------  ----------  -----------
      1            15            0         2019-08-31       200
      2            16            2         2019-08-28       100
      3            18           25         2019-08-18        75

最上面的列ID依次如下:

      Code1         Code2          Code3          Date  -   Stock status
│ arti-cd-base │ arti-cd-sfx │ adfc-cd-diffco │   stof-dt   │ stof-qty-op │

有没有什么方法可以通过 SQL 来实现?我找到了一个通过命令仅显示一行的选项:"offset 0 row fetch first 1 row only",但这只显示一行,但不尊重其他三列中给出的一组产品 ID 的一行(arti-cd-base , arti-cd-sfx 和 adfc-cd-diffco)。有人会看到任何方法吗?

查看此选项:

SELECT *
FROM (
    SELECT * 
    ,   ROW_NUMBER() OVER ( PARTITION BY arti_cd_base ORDER BY stof_dt DESC) AS rwn
    FROM yourTable
    ) x
WHERE x.rwn = 1 

或者你的情况:

    SELECT *
    FROM ( 
        SELECT stof_0."arti-cd-base"
        , stof_0."arti-cd-sfx"
        , stof_0."adfc-cd-diffco"
        , stof_0."dcmf-nr"
        , stof_0."stof-dt"
        , stof_0."stof-qty-op"
        , stof_0."stof-qty-nop"
        , stof_0."stof-qty-brok"
        , stof_0."stof-qty-brok-ok"
        , stof_0."stof-qty-ext"
        , stof_0."stof-qty-dock"
        , stof_0."stof-qty-trans"
        , stof_0."stof-qty-diff"
        , stof_0."stof-qty-fin-qty"
        , stof_0."stof-qty-fin-temp"
        , stof_0."stof-am" 
        , ROW_NUMBER() OVER (PARTITION BY stof_0."arti-cd-base" ORDER BY stof_0."stof-dt" DESC ) AS rwn
        FROM NILOS.PUB.stof stof_0 
        WHERE (stof_0."arti-cd-base"=1) 
        AND (stof_0."arti-cd-sfx"=15) 
        AND (stof_0."adfc-cd-diffco"=0) 
        ) x
    WHERE x.rwn = 1 

或者:

SELECT x.*
FROM (
        SELECT stof_0."arti-cd-base"
        , stof_0."arti-cd-sfx"
        , stof_0."adfc-cd-diffco"
        , stof_0."dcmf-nr"
        , stof_0."stof-dt"
        , stof_0."stof-qty-op"
        , stof_0."stof-qty-nop"
        , stof_0."stof-qty-brok"
        , stof_0."stof-qty-brok-ok"
        , stof_0."stof-qty-ext"
        , stof_0."stof-qty-dock"
        , stof_0."stof-qty-trans"
        , stof_0."stof-qty-diff"
        , stof_0."stof-qty-fin-qty"
        , stof_0."stof-qty-fin-temp"
        , stof_0."stof-am" 
        FROM NILOS.PUB.stof stof_0 
        WHERE (stof_0."arti-cd-base"=1) 
        AND (stof_0."arti-cd-sfx"=15) 
        AND (stof_0."adfc-cd-diffco"=0) 
    ) x
INNER JOIN ( SELECT stof_1."arti-cd-base"
            ,   MAX(stof_1."stof-dt") AS max_stof_dt
         FROM NILOS.PUB.stof stof_1 
         GROUP BY stof_1."arti-cd-base" ) y ON x"arti-cd-base" = y."arti-cd-base"
                                            AND x."stof-dt" = y."max_stof_dt"

此 returns 结果集分区内行的序号,每个分区中的第一行从 1 开始。 因此,在您的情况下,分区是 arti_cd_base,我们按每个分区的最旧日期排序。每个分区的最旧日期始终为 1,这就是为什么有条件要求此函数的结果必须等于 1。

您似乎想保留聚合中最后一列的第一个值。 Oracle 提供此功能,使用 keep:

select "arti-cd-base", "arti-cd-sfx", "adfc-cd-diffco",  
       max("stof-dt") as "stof-dt",
       max("stof-qty-op") keep (dense_rank first order by "stof-dt" desc) as "stof-qty-op"
from t
group by "arti-cd-base", "arti-cd-sfx", "adfc-cd-diffco";