给出SQL Server 2005中的下表:
ID Col1 Col2 Col3
-- ---- ---- ----
1 3 34 76
2 32 976 24
3 7 235 3
4 245 1 792
Run Code Online (Sandbox Code Playgroud)
编写产生以下结果的查询的最佳方法是什么(即产生最终列的查询 - 包含每行的Col1,Col2和Col3中的minium值的列)?
ID Col1 Col2 Col3 TheMin
-- ---- ---- ---- ------
1 3 34 76 3
2 32 976 24 24
3 7 235 3 3
4 245 1 792 1
Run Code Online (Sandbox Code Playgroud)
更新:
为了澄清(正如我在演讲中所说),在真实场景中,数据库已正确规范化.这些"数组"列不在实际表中,而是在报表中所需的结果集中.新要求是报告还需要此MinValue列.我无法更改基础结果集,因此我期待T-SQL获得一个方便的"走出监狱卡".
我尝试了下面提到的CASE方法并且它有效,尽管它有点麻烦.它也比答案中说明的更复杂,因为你需要满足同一行中有两个最小值的事实.
无论如何,我想我会发布我目前的解决方案,鉴于我的限制,它的效果非常好.它使用UNPIVOT运算符:
with cte (ID, Col1, Col2, Col3)
as
(
select ID, …Run Code Online (Sandbox Code Playgroud) 我在Hive中有一个包含5列的表,即email,a_first_date,b_first_date,c_first_date,d_first_date.
a,b,c,d是用户可以采取的4种不同动作,上表中的4列表示用户进行第一次相应动作的日期.例如,'a_first_date'中的值具有用户执行操作a的日期.
输出:我想要的是2列电子邮件,overall_first_date,即用户第一次行动的日期?
示例表:(假设所有值都是除电子邮件之外的BIGINT类型)
email,a_first_date,b_first_date,c_first_date,d_first_date
abc,20140707,20140702,20140801,20140907
xyz,20140107,20140822,20140201,20141007
输出:
email,overall_first_date
abc,20140702
xyz,20140107
可能的几个解决方案是编写UDF或使用IF ELSE将这些值相互比较,然后找到最小值,但这将涉及大量的比较.
或者我可以做一个:
select email, min(action) as overall_first_date from
(
select email, a_first_date as action from mytable
UNION ALL
select email, b_first_date as action from mytable
UNION ALL
select email, c_first_date as action from mytable
UNION ALL
select email, d_first_date as action from mytable
) q1
GROUP BY email
Run Code Online (Sandbox Code Playgroud)
但这又不是一个好方法.
有人可以建议一个更好的方法来实现这一目标吗?