【问题标题】:Get the maximum value based on two columns values using foor loop in SQL在 SQL 中使用 for 循环根据两列值获取最大值
【发布时间】:2020-11-18 16:39:46
【问题描述】:

我创建了一个包含 4 列的假表: Farmer_name,crop_name,year,working_days

该表描述了每个农民在过去三年中的作物和今年的季节长度:

(红色的是同一个种植者)

>>>farmer   crop_name   year  working_days
   red       potatoe    2018   110
   red       onion      2019   120   
   red       onion      2020   130
   red       wheat      2019   70
   blue      coffe      2018   194
   blue      coffee     2019   115

我需要为每个农民找出每年工作日的最大价值。

例如,如果对于 2018 年的红色农民,我们在 working_days 中的值为:124,145 和 70,我想获得如下所示的新表:

>>>  Farmer      year      working_days
       red        2018     145
       red        2019     190
       red        2020     175
       blue       2018     72

*示例中的蓝色是因为我想为我拥有的所有农民获得它,而不仅仅是为红色的。

我更多地使用 python,我觉得我想使用 for 循环,但从阅读中我发现在 sql 中这是不可能的,并且需求是使用 SQL 来完成。我看到有一个使用 while 循环的选项,但是当我在这里有两列需要考虑(种植者名称+年份)时,我不知道该怎么做。

我已经看到了将 while 循环用作 for 的示例:

DECLARE @cnt INT = 0;

WHILE @cnt < 10
BEGIN
   PRINT 'Inside simulated FOR LOOP on TechOnTheNet.com';
   SET @cnt = @cnt + 1;
END;

PRINT 'Done simulated FOR LOOP on TechOnTheNet.com';
GO

(来自这里:https://www.techonthenet.com/sql_server/loops/for_loop.php) (这里也类似:https://www.sqlshack.com/sql-while-loop-with-simple-examples/) 但我不明白如何在这种情况下使用计数器,我需要最大值,我还需要为每个农民检查它。

我的最终目标:为每个农民获得一张包含所有农民姓名、年份和该年“working_days”最大值的表格。

【问题讨论】:

  • 请标记您正在使用的数据库
  • @JimMacaulay 刚刚添加(我创建的假数据库+添加示例)

标签: sql oracle for-loop while-loop


【解决方案1】:

我认为您可以通过以下方式使用max() 函数和group by 表达式:

SELECT
    farmer,
    year,
    max(working_days)
FROM
    farmer_table
GROUP BY
    farmer,
    year 

【讨论】:

  • 这给出了正确的行数,但它并没有真正取最大值(对于我在图片中显示的种植者,它给出的最大值是 70 而不是 145)
【解决方案2】:

如果您使用的是支持分析函数的 SQL 版本,那么ROW_NUMBER 是这里的方法:

WITH cte AS (
    SELECT *, ROW_NUMBER() OVER (PARTITION BY Farmer, year ORDER BY working_days DESC) rn
    FROM yourTable
)

SELECT Farmer, year, working_days
FROM cte
WHERE rn = 1;

另一个使用连接但不使用分析函数的版本是:

SELECT t1.Farmer, t1.year, t1.working_days
FROM yourTable t1
INNER JOIN
(
    SELECT Farmer, year, MAX(working_days) AS max_working_days
    FROM yourTable
    GROUP BY Farmer, year
) t2
    ON t1.Farmer = t2.Farmer AND t1.year = t2.year AND
       t1.working_days = t2.working_days;

请注意,通常通过使用游标迭代记录来解决此问题不是。 SQL 本质上是基于设置的,这意味着 SQL 查询已经遍历所有记录,而不需要显式游标。

【讨论】:

    【解决方案3】:

    请使用以下查询,

    select farmer, year, max(working_days) from table_name
    group by farmer, year order by year;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-24
      • 1970-01-01
      • 2021-11-06
      • 2018-09-21
      • 1970-01-01
      相关资源
      最近更新 更多