【问题标题】:How to use MAX from single column from single table while querying multiple columns from multiple tables如何在从多个表中查询多个列时从单个表中的单个列中使用 MAX
【发布时间】:2020-01-11 16:35:21
【问题描述】:

所以我收到了我公司某人的一些数据请求。此数据请求需要对来自多个表的多个列进行 SQL 查询,但只能是来自这些表之一的列的最新事件。这是踢球者......每个表都有一个与另一个表共享的列。所以为了得到这份“报告”,我必须一点一点地做。

在我意识到我只需要对其中一个表进行最新更新之前,我的初始查询是这样的:

SELECT a.description  AS "Description", 
       a.pricing      AS "Price", 
       b.id           AS "ID", 
       c.descriptionb AS "DescriptionB", 
       c.date         AS "date", 
       d.descriptionc AS "DescriptionC" 
FROM   database.table1 a, 
       database.table2 b, 
       database.table3 c, 
       database.table4 d 
WHERE  a.description = b.descriptive_info 
       AND b.id = c.comp_id 
       AND c.descriptionb = d.long_description
       AND d.id_for_a = a.id
       AND a.company IN ( '000', '001', '002', '003', '004' ) 
       AND b.expdate >= Now()

我意识到上面的“c.date”只需要显示每个唯一 ID/DescriptionC 的最近日期。

这是初始查询的示例结果:

Description|Price   |ID       |DescriptionB   |date     |DescriptionC
---------------------------------------------------------------------
Computer   |300     |554      |5% Off         |3/2/2010 |Includes CPU
Computer   |300     |554      |5% Off         |3/2/2010 |Includes DOG
Computer   |300     |554      |5% Off         |3/2/2010 |Includes CAT 
Computer   |300     |554      |9% Off         |4/3/2011 |Includes CPU
Computer   |300     |554      |9% Off         |4/3/2011 |Includes DOG
Computer   |300     |554      |9% Off         |4/3/2011 |Includes CAT 
Computer   |300     |554      |7% Off         |9/1/2019 |Includes CPU
Computer   |300     |554      |7% Off         |9/1/2019 |Includes DOG
Computer   |300     |554      |7% Off         |9/1/2019 |Includes CAT 
Printer    |75      |801      |3% Off         |6/3/2012 |Includes DOS
Printer    |75      |801      |3% Off         |6/3/2012 |Includes PIG
Printer    |75      |801      |3% Off         |6/3/2012 |Includes RAT
Printer    |75      |801      |9% Off         |8/3/2013 |Includes DOS
Printer    |75      |801      |9% Off         |8/3/2013 |Includes PIG
Printer    |75      |801      |9% Off         |8/3/2013 |Includes RAT
Printer    |75      |801      |1% Off         |1/3/2019 |Includes DOS
Printer    |75      |801      |1% Off         |1/3/2019 |Includes PIG
Printer    |75      |801      |1% Off         |1/3/2019 |Includes RAT

下面是 Laurenz 的查询结果:

Description|Price   |ID       |DescriptionB   |date     |DescriptionC
---------------------------------------------------------------------
Computer   |300     |554      |7% Off         |9/1/2019 |Includes CAT

...关闭但还没有完全到那里。

期望的结果:

Description|Price   |ID       |DescriptionB   |date     |DescriptionC
---------------------------------------------------------------------
Computer   |300     |554      |7% Off         |9/1/2019 |Includes CPU
Computer   |300     |554      |7% Off         |9/1/2019 |Includes DOG
Computer   |300     |554      |7% Off         |9/1/2019 |Includes CAT 
Printer    |75      |801      |1% Off         |1/3/2019 |Includes DOS
Printer    |75      |801      |1% Off         |1/3/2019 |Includes PIG
Printer    |75      |801      |1% Off         |1/3/2019 |Includes RAT

正如您所见,“同一产品”有多个日期,具有不同描述的重复产品等。我基本上只想要每个唯一 ID/描述 C 具有最新“日期”的行。希望这比我原来的帖子更容易理解。

顺便说一句,这些是简化的示例,因为我不想给我的公司带来麻烦,但查询和概念是相同的。如果您可以多次想象多个产品具有每个产品的多个实例,那么您可以想象数据集可以有多大。我只关心每个唯一 ID/DescriptionC 的最新实例。

【问题讨论】:

  • 几行数据和相应的预期输出可能会帮助我们提供更准确的答案。
  • 那么您只需要最新一行的哪些组?你怎么看,哪一行比另一行新?也许显示所有表的所有字段可能会有所帮助

标签: sql postgresql date select greatest-n-per-group


【解决方案1】:

非常感谢大家。 Hal McGee 的回答基本上是正确的!我只需要调整一些东西。这是我最终使用的完整查询的示例,该查询的功能符合我的需要:

SELECT *
FROM (
    SELECT 
        a.description  AS "Description",
        a.pricing      AS "Price", 
        b.string       AS "String", 
        c.description  AS "Description", 
        c.date         AS "date", 
        d.descriptionb AS "DescriptionB",
        ROW_NUMBER() OVER (PARTITION BY d.descriptionc, b.id ORDER BY c.date DESC ) AS rn
    FROM
       database.table1 a 
       INNER JOIN database.table2 b ON a.id = b.table1_id 
       INNER JOIN database.table3 c ON b.element = c.table2_element AND b.expdate >= Now()
       INNER JOIN database.table4 d ON c.value = d.table3_value 
    WHERE 
        a.company IN ( '000', '001', '002', '003', '004' ) 
) x WHERE rn = 1;

【讨论】:

    【解决方案2】:

    下面的sql可以用来解题:

    SELECT *
    FROM (
        SELECT 
            a.description  AS "Description",
    
            a.pricing      AS "Price", 
            b.string       AS "String", 
            c.description  AS "Description", 
            c.date         AS "date", 
            d.descriptionb AS "DescriptionB",
            ROW_NUMBER() OVER (ORDER BY c.date DESC PARTITION BY B.ID ) AS rn
        FROM
           database.table1 a 
           INNER JOIN database.table2 b ON a.id = b.table1_id 
           INNER JOIN database.table3 c ON b.element = c.table2_element AND b.expdate >= Now()
           INNER JOIN database.table4 d ON c.value = d.table3_value 
        WHERE 
            a.company IN ( '000', '001', '002', '003', '004' ) 
    ) x WHERE rn = 1;
    

    【讨论】:

      【解决方案3】:

      我了解,在当前查询的结果中,您只想选择在c.date 上具有最大值的那个。

      一种解决方案是将现有查询转换为子查询,并使用ROW_NUMBER() 对记录进行降序排列c.date。然后,外部查询可以只过滤排名最高的记录。

      查询:

      SELECT *
      FROM (
          SELECT 
              a.description  AS "Description", 
              a.pricing      AS "Price", 
              b.string       AS "String", 
              c.description  AS "Description", 
              c.date         AS "date", 
              d.descriptionb AS "DescriptionB",
              ROW_NUMBER() OVER (ORDER BY c.date DESC) AS rn
          FROM
             database.table1 a 
             INNER JOIN database.table2 b ON a.id = b.table1_id 
             INNER JOIN database.table3 c ON b.element = c.table2_element AND b.expdate >= Now()
             INNER JOIN database.table4 d ON c.value = d.table3_value 
          WHERE 
              a.company IN ( '000', '001', '002', '003', '004' ) 
      ) x WHERE rn = 1;
      

      PS:

      • 总是更喜欢 显式连接,而不是老式的隐式连接;我相应地更改了初始查询

      • 如果您需要按分区划分的最大日期(如果没有看到示例数据,这并不明显),那么您只需在ROW_NUMBER() 函数中添加一个PARTITION BY 子句。

      【讨论】:

      • 太棒了,消除了错误,但是,现在它不喜欢倒数第二个“WHERE”子句:错误:“WHERE”处或附近的语法错误这是一个sn-p ACTUAL 更大的查询围绕“WHERE”语句的所有内容:INNER JOIN viper_logical_1.promotion_relatedmarketitems i ON i.element = b.externalid WHERE a.externalid IN ('5957962','2882541') x WHERE rn = 1 LINE 35:在哪里
      • @user2079024: 嗯,很难判断你的实际查询中有什么问题......你可以做的一件事是尝试缩小问题范围:首先运行子查询,看看它是否有效,然后运行整个查询。
      • 好的...所以这个查询已经接近了,但还没有完成。我更新了我对问题、结果和期望结果的原始描述。希望这会让事情更清楚我想要完成的事情。再次,我们将不胜感激任何额外的帮助!
      猜你喜欢
      • 1970-01-01
      • 2013-10-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多