【问题标题】:Returning max value in multiple columns and adjacent column返回多列和相邻列中的最大值
【发布时间】:2015-02-18 15:55:53
【问题描述】:

关于 SQL Server 2014 的查询问题。

我在查询从各个列返回 MAX 值时遇到了一些问题。

我正在运行的当前查询如下,这可以很好地从为每个日期指定的列中返回最大值。

SELECT ws.ExerciseID, 
ws.Date,
(SELECT Max(v) FROM 
(VALUES (WeightReps1), (WeightReps2), (WeightReps3), (WeightReps4), (WeightReps5)
   , (WeightReps6), (WeightReps7), (WeightReps8), (WeightReps9), (WeightReps10)
) 
AS value(v)
) 
as [Max Weight]
FROM workoutsessions ws
join ExerciseCultures ec on ws.ExerciseID = ec.ExerciseID
where ec.Name = 'Bench Press'

所以这显示了这些列的最大值。极好的。然而,每列“weightreps”列都有一个相邻的“Reps”列。我需要从上面的列中返回最大值,但仅在相邻的“reps”列大于或等于某个值的情况下。

我在下面提供了一个示例:

ExerciseID | WorkoutID | Date       | WeightReps1 | Reps1 | Weightreps2 | Reps2 | Weightreps3 | Reps3
105        | 201      | 11/08/2014 | 50          | 9     | 65          | 3     | 75             | 1
 105       | 202      | 13/08/2014 | 55          | 6     | 70          | 2     | 77        | 1

所以在上面的示例中,如果我只想返回 'reps' 列大于 2 的最大值。我会返回值“70”,因为这是相邻 reps 列等于或大于 2 的最大值。

我已经尝试了下面的代码,但这将带回任何代表列大于 2 的最高值 - 没有帮助。

SELECT top 1 ec.Name, Date,
  (SELECT Max(v) 
   FROM (VALUES (WeightReps1), (WeightReps2), (WeightReps3), (WeightReps4), (WeightReps5)
   , (WeightReps6), (WeightReps7), (WeightReps8), (WeightReps9), (WeightReps10)
   ) AS value(v)
   ) as [Weight]
FROM workoutsessions ws
join ExerciseCultures ec on ws.ExerciseID = ec.ExerciseID
where 
ec.Name = 'Bench Press'
and ws.reps1 >= '6'
or
ec.Name = 'Bench Press'
and ws.reps2 >= '6'
or
ec.Name = 'Bench Press'
and ws.reps3 >= '6'
or
ec.Name = 'Bench Press'
and ws.reps4 >= '6'
or
ec.Name = 'Bench Press'
and ws.reps5 >= '6'
or
ec.Name = 'Bench Press'
and ws.reps6 >= '6'
or
ec.Name = 'Bench Press'
and ws.reps7 >= '6'
or
ec.Name = 'Bench Press'
and ws.reps8 >= '6'
or
ec.Name = 'Bench Press'
and ws.reps9 >= '6'
or
ec.Name = 'Bench Press'
and ws.reps10 >= '6'
order by weight desc

有什么想法我哪里出错了吗?

谢谢。

【问题讨论】:

  • 如果您的基表已标准化,这将很简单。你有机会修桌子吗?这不仅可以解决这个问题,还可以解决未来的许多其他挑战。
  • 我忘记为每一行包含一个“WorkoutID”列。该表仅允许将一个 WorkoutID 和 ExerciseID 结合使用。

标签: sql sql-server tsql sql-server-2014


【解决方案1】:

你可以改变这个子查询:

SELECT Max(v)
FROM 
  (
    VALUES
      (WeightReps1), (WeightReps2), (WeightReps3), (WeightReps4), (WeightReps5),
      (WeightReps6), (WeightReps7), (WeightReps8), (WeightReps9), (WeightReps10)
  ) AS value(v)

到这里:

SELECT Max(w)
FROM 
  (
    VALUES
      (WeightReps1, Reps1), (WeightReps2, Reps2),
      (WeightReps3, Reps3), (WeightReps4, Reps4),
      (WeightReps5, Reps5), (WeightReps6, Reps6),
      (WeightReps7, Reps7), (WeightReps8, Reps8),
      (WeightReps9, Reps9), (WeightReps10, Reps10)
  ) AS value(w, r)
WHERE
  r >= ... /* some value */

【讨论】:

  • 干净,比我的好。
【解决方案2】:

您可以在VALUES 子句中使用CASE 表达式:

SELECT ws.ExerciseID, 
ws.Date,
(SELECT Max(v) FROM 
(VALUES (CASE WHEN Reps1 > 6 THEN WeightReps1 ELSE NULL END), 
        (CASE WHEN Reps2 > 6 THEN WeightReps2 ELSE NULL END), 
        (CASE WHEN Reps3 > 6 THEN WeightReps3 ELSE NULL END), 
            ... etc
) 
AS value(v)
) 
as [Max Weight]
FROM workoutsessions ws
join ExerciseCultures ec on ws.ExerciseID = ec.ExerciseID
where ec.Name = 'Bench Press'

这样,WeightRepsx 值将被忽略,如果“相邻”Repsx大于特定值(根据您的要求)。

这当然是相当丑陋的,但它是一个选项,因为你的表没有正确规范化。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多