【问题标题】:How to "fetch first 1 row only" per IDs in 3 different columns?如何在 3 个不同的列中“仅获取前 1 行”每个 ID?
【发布时间】:2019-08-13 08:25:27
【问题描述】:

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

这就是我的桌子现在的样子:

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-cd 组合仅显示具有最新日期 (stpf-dt) 和库存状态 (stof-qty-op) 的行-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 来实现这一点?我找到了一个仅通过命令显示一行的选项:“偏移 0 行仅获取前 1 行”,但是这仅显示 1 行,但不尊重其他三列中给出的一组产品 ID 中的一行( arti-cd-base、arti-cd-sfx 和 adfc-cd-diffco)。有人能看穿吗?

【问题讨论】:

  • 基本上,根据最新日期考虑 Code1 + Code2 + Code3 就足够了......并且只显示该最新日期的一个值。应遵循数量值。
  • 这里的大多数人都希望样本表数据和预期结果为格式化文本,而不是图像(或图像链接)。
  • 没问题,每行数据前加4个空格即可:)

标签: sql oracle ms-query excelquery


【解决方案1】:

查看此选项:

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"

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

【讨论】:

  • 好的,考虑到到目前为止我在 SQL 中有以下代码,您建议在哪里粘贴您的解决方案?到目前为止,我收到错误:S
  • 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)
  • 按 stof_0 排序。"arti-cd-base", stof_0."arti-cd-sfx", stof_0."adfc-cd-diffco", stof_0."stof-dt" DESC跨度>
  • My Ms Query 现在使用新解决方案返回以下错误:“无法添加表(。”:S。有什么想法吗?
  • 你在创建新表吗?该查询似乎一切正常。
【解决方案2】:

您似乎希望将最后一列的第一个值保留在聚合中。 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";

【讨论】:

  • 谢谢。我真的很想告诉你这是成功的......但是......再次出现同样的错误:“无法添加表(。” :( Excel 365 女士 / 查询女士 / SQL 使用 Oracle 数据库中的数据......跨度>
  • @Zdenda 。 . .这回答了您在这里提出的问题。如果您还有其他问题,您应该提出一个问题。
猜你喜欢
  • 2020-01-13
  • 1970-01-01
  • 1970-01-01
  • 2021-06-11
  • 1970-01-01
  • 1970-01-01
  • 2017-07-30
  • 2020-02-21
  • 2023-02-02
相关资源
最近更新 更多