如何在每行最多几列中返回1个值:
表名
[Number, Date1, Date2, Date3, Cost]
我需要返回这样的内容:
[Number, Most_Recent_Date, Cost]
查询?
答案 0 :(得分:771)
这是使用T-SQL和SQL Server的Max
功能的另一个很好的解决方案
SELECT [Other Fields],
(SELECT Max(v)
FROM (VALUES (date1), (date2), (date3),...) AS value(v)) as [MaxDate]
FROM [YourTableName]
答案 1 :(得分:149)
好吧,您可以使用CASE语句:
SELECT
CASE
WHEN Date1 >= Date2 AND Date1 >= Date3 THEN Date1
WHEN Date2 >= Date1 AND Date2 >= Date3 THEN Date2
WHEN Date3 >= Date1 AND Date3 >= Date2 THEN Date3
ELSE Date1
END AS MostRecentDate
[对于Microsoft SQL Server 2008 及以上,您可以考虑下面的Sven更简单的答案。]
答案 2 :(得分:118)
如果您使用的是MySQL,则可以使用
SELECT GREATEST(col1, col2 ...) FROM table
答案 3 :(得分:59)
还有3种方法,其中UNPIVOT
(1)是迄今为止最快的,其次是Simulated Unpivot(3),它慢于(1)但仍然快于(2)
CREATE TABLE dates
(
number INT PRIMARY KEY ,
date1 DATETIME ,
date2 DATETIME ,
date3 DATETIME ,
cost INT
)
INSERT INTO dates
VALUES ( 1, '1/1/2008', '2/4/2008', '3/1/2008', 10 )
INSERT INTO dates
VALUES ( 2, '1/2/2008', '2/3/2008', '3/3/2008', 20 )
INSERT INTO dates
VALUES ( 3, '1/3/2008', '2/2/2008', '3/2/2008', 30 )
INSERT INTO dates
VALUES ( 4, '1/4/2008', '2/1/2008', '3/4/2008', 40 )
GO
UNPIVOT
)SELECT number ,
MAX(dDate) maxDate ,
cost
FROM dates UNPIVOT ( dDate FOR nDate IN ( Date1, Date2,
Date3 ) ) as u
GROUP BY number ,
cost
GO
SELECT number ,
( SELECT MAX(dDate) maxDate
FROM ( SELECT d.date1 AS dDate
UNION
SELECT d.date2
UNION
SELECT d.date3
) a
) MaxDate ,
Cost
FROM dates d
GO
UNPIVOT
);WITH maxD
AS ( SELECT number ,
MAX(CASE rn
WHEN 1 THEN Date1
WHEN 2 THEN date2
ELSE date3
END) AS maxDate
FROM dates a
CROSS JOIN ( SELECT 1 AS rn
UNION
SELECT 2
UNION
SELECT 3
) b
GROUP BY Number
)
SELECT dates.number ,
maxD.maxDate ,
dates.cost
FROM dates
INNER JOIN MaxD ON dates.number = maxD.number
GO
DROP TABLE dates
GO
答案 4 :(得分:16)
以下两个样本中的任何一个都可以使用:
SELECT MAX(date_columns) AS max_date
FROM ( (SELECT date1 AS date_columns
FROM data_table )
UNION
( SELECT date2 AS date_columns
FROM data_table
)
UNION
( SELECT date3 AS date_columns
FROM data_table
)
) AS date_query
第二个是lassevk's答案的附加组件。
SELECT MAX(MostRecentDate)
FROM ( SELECT CASE WHEN date1 >= date2
AND date1 >= date3 THEN date1
WHEN date2 >= date1
AND date2 >= date3 THEN date2
WHEN date3 >= date1
AND date3 >= date2 THEN date3
ELSE date1
END AS MostRecentDate
FROM data_table
) AS date_query
答案 5 :(得分:9)
标量函数会导致各种性能问题,因此如果可能,最好将逻辑包装到内联表值函数中。这是我用来替换一些用户定义函数的函数,这些函数从最多十个日期的列表中选择最小/最大日期。在我的100万行数据集上测试时,标量函数花了15分钟才杀死查询,内联TVF花了1分钟,这与将结果集选择到临时表中的时间相同。要使用它,请从SELECT或CROSS APPLY中的子查询调用该函数。
CREATE FUNCTION dbo.Get_Min_Max_Date
(
@Date1 datetime,
@Date2 datetime,
@Date3 datetime,
@Date4 datetime,
@Date5 datetime,
@Date6 datetime,
@Date7 datetime,
@Date8 datetime,
@Date9 datetime,
@Date10 datetime
)
RETURNS TABLE
AS
RETURN
(
SELECT Max(DateValue) Max_Date,
Min(DateValue) Min_Date
FROM (
VALUES (@Date1),
(@Date2),
(@Date3),
(@Date4),
(@Date5),
(@Date6),
(@Date7),
(@Date8),
(@Date9),
(@Date10)
) AS Dates(DateValue)
)
答案 6 :(得分:8)
对于T-SQL(MSSQL 2008 +)
SELECT
(SELECT
MAX(MyMaxName)
FROM ( VALUES
(MAX(Field1)),
(MAX(Field2))
) MyAlias(MyMaxName)
)
FROM MyTable1
答案 7 :(得分:8)
DECLARE @TableName TABLE (Number INT, Date1 DATETIME, Date2 DATETIME, Date3 DATETIME, Cost MONEY)
INSERT INTO @TableName
SELECT 1, '20000101', '20010101','20020101',100 UNION ALL
SELECT 2, '20000101', '19900101','19980101',99
SELECT Number,
Cost ,
(SELECT MAX([Date])
FROM (SELECT Date1 AS [Date]
UNION ALL
SELECT Date2
UNION ALL
SELECT Date3
)
D
)
[Most Recent Date]
FROM @TableName
答案 8 :(得分:5)
SELECT
CASE
WHEN Date1 >= Date2 AND Date1 >= Date3 THEN Date1
WHEN Date2 >= Date3 THEN Date2
ELSE Date3
END AS MostRecentDate
由于案例陈述按顺序进行评估,因此写出并略过评估步骤会稍微容易一些。
答案 9 :(得分:4)
问题:选择给予实体的最低费率值 要求:代理商费率可以为空
[MinRateValue] =
CASE
WHEN ISNULL(FitchRating.RatingValue, 100) < = ISNULL(MoodyRating.RatingValue, 99)
AND ISNULL(FitchRating.RatingValue, 100) < = ISNULL(StandardPoorsRating.RatingValue, 99)
THEN FitchgAgency.RatingAgencyName
WHEN ISNULL(MoodyRating.RatingValue, 100) < = ISNULL(StandardPoorsRating.RatingValue , 99)
THEN MoodyAgency.RatingAgencyName
ELSE ISNULL(StandardPoorsRating.RatingValue, 'N/A')
END
灵感来自this answer
的Nat答案 10 :(得分:4)
不幸的是Lasse's answer虽然看似显而易见,却有一个至关重要的缺陷。它无法处理NULL值。任何单个NULL值都会导致返回Date1。不幸的是,任何修复该问题的尝试都会变得非常混乱,并且不能很好地扩展到4个或更多值。
databyss's first answer看起来很好。但是,目前尚不清楚答案是否可以从多表连接中轻易推断为3个值,而不是从单个表中推导出更简单的3个值。我想避免将这样的查询转换成子查询只是为了得到最多3列,我也很确定databyss的优点可以清理一下。
所以不用多说,这是我的解决方案(源于数据表的想法) 它使用交叉连接选择常量来模拟多表连接的效果。需要注意的重要一点是,所有必需的别名都能正确执行(并非总是如此),这样可以使模式非常简单,并且可以通过其他列进行相当大的扩展。
DECLARE @v1 INT ,
@v2 INT ,
@v3 INT
--SET @v1 = 1 --Comment out SET statements to experiment with
--various combinations of NULL values
SET @v2 = 2
SET @v3 = 3
SELECT ( SELECT MAX(Vals)
FROM ( SELECT v1 AS Vals
UNION
SELECT v2
UNION
SELECT v3
) tmp
WHERE Vals IS NOT NULL -- This eliminates NULL warning
) AS MaxVal
FROM ( SELECT @v1 AS v1
) t1
CROSS JOIN ( SELECT @v2 AS v2
) t2
CROSS JOIN ( SELECT @v3 AS v3
) t3
答案 11 :(得分:3)
使用CROSS APPLY(2005年以上)....
SELECT MostRecentDate
FROM SourceTable
CROSS APPLY (SELECT MAX(d) MostRecentDate FROM (VALUES (Date1), (Date2), (Date3)) AS a(d)) md
答案 12 :(得分:3)
从SQL Server 2012开始,我们可以使用IIF。
DECLARE @Date1 DATE='2014-07-03';
DECLARE @Date2 DATE='2014-07-04';
DECLARE @Date3 DATE='2014-07-05';
SELECT IIF(@Date1>@Date2,
IIF(@Date1>@Date3,@Date1,@Date3),
IIF(@Date2>@Date3,@Date2,@Date3)) AS MostRecentDate
答案 13 :(得分:3)
如果您使用的是SQL Server 2005,则可以使用UNPIVOT功能。这是一个完整的例子:
create table dates
(
number int,
date1 datetime,
date2 datetime,
date3 datetime
)
insert into dates values (1, '1/1/2008', '2/4/2008', '3/1/2008')
insert into dates values (1, '1/2/2008', '2/3/2008', '3/3/2008')
insert into dates values (1, '1/3/2008', '2/2/2008', '3/2/2008')
insert into dates values (1, '1/4/2008', '2/1/2008', '3/4/2008')
select max(dateMaxes)
from (
select
(select max(date1) from dates) date1max,
(select max(date2) from dates) date2max,
(select max(date3) from dates) date3max
) myTable
unpivot (dateMaxes For fieldName In (date1max, date2max, date3max)) as tblPivot
drop table dates
答案 14 :(得分:1)
请尝试使用UNPIVOT
:
SELECT MAX(MaxDt) MaxDt
FROM tbl
UNPIVOT
(MaxDt FOR E IN
(Date1, Date2, Date3)
)AS unpvt;
答案 15 :(得分:1)
我更喜欢基于案例的解决方案,当时我的假设是,与具有交叉应用,values(),自定义函数等的其他解决方案相比,它对可能的性能下降的影响最小。
在这种情况下,大多数情况下都会处理空值:
[X, Y] = np.meshgrid(x, y)
fig, ax = plt.subplots()
sc = ax.scatter(x, y)
ax.set_aspect("equal")
ax.set_xlim(0, 80)
ax.set_ylim(0, 80)
结果是:
SELECT
CASE
WHEN Date1 > coalesce(Date2,'0001-01-01') AND Date1 > coalesce(Date3,'0001-01-01') THEN Date1
WHEN Date2 > coalesce(Date3,'0001-01-01') THEN Date2
ELSE Date3
END AS MostRecentDate
, *
from
(values
( 1, cast('2001-01-01' as Date), cast('2002-01-01' as Date), cast('2003-01-01' as Date))
,( 2, cast('2001-01-01' as Date), cast('2003-01-01' as Date), cast('2002-01-01' as Date))
,( 3, cast('2002-01-01' as Date), cast('2001-01-01' as Date), cast('2003-01-01' as Date))
,( 4, cast('2002-01-01' as Date), cast('2003-01-01' as Date), cast('2001-01-01' as Date))
,( 5, cast('2003-01-01' as Date), cast('2001-01-01' as Date), cast('2002-01-01' as Date))
,( 6, cast('2003-01-01' as Date), cast('2002-01-01' as Date), cast('2001-01-01' as Date))
,( 11, cast(NULL as Date), cast('2002-01-01' as Date), cast('2003-01-01' as Date))
,( 12, cast(NULL as Date), cast('2003-01-01' as Date), cast('2002-01-01' as Date))
,( 13, cast('2003-01-01' as Date), cast(NULL as Date), cast('2002-01-01' as Date))
,( 14, cast('2002-01-01' as Date), cast(NULL as Date), cast('2003-01-01' as Date))
,( 15, cast('2003-01-01' as Date), cast('2002-01-01' as Date), cast(NULL as Date))
,( 16, cast('2002-01-01' as Date), cast('2003-01-01' as Date), cast(NULL as Date))
,( 21, cast('2003-01-01' as Date), cast(NULL as Date), cast(NULL as Date))
,( 22, cast(NULL as Date), cast('2003-01-01' as Date), cast(NULL as Date))
,( 23, cast(NULL as Date), cast(NULL as Date), cast('2003-01-01' as Date))
,( 31, cast(NULL as Date), cast(NULL as Date), cast(NULL as Date))
) as demoValues(id, Date1,Date2,Date3)
order by id
;
答案 16 :(得分:0)
基于来自ScottPletcher的http://www.experts-exchange.com/Microsoft/Development/MS-SQL-Server/Q_24204894.html解决方案 我创建了一组函数(例如GetMaxOfDates3,GetMaxOfDates13),使用UNION ALL查找最多13个Date值。 见T-SQL function to Get Maximum of values from the same row 但是,在编写这些函数时我没有考虑过UNPIVOT解决方案
答案 17 :(得分:0)
您可以创建一个函数来传递日期,然后将函数添加到select语句中,如下所示。 选择数字,dbo.fxMost_Recent_Date(Date1,Date2,Date3),成本
create FUNCTION fxMost_Recent_Date
( @ Date1 smalldatetime, @ Date2 smalldatetime, @ Date3 smalldatetime ) 返回smalldatetime 如 开始 DECLARE @Result smalldatetime
declare @MostRecent smalldatetime
set @MostRecent='1/1/1900'
if @Date1>@MostRecent begin set @MostRecent=@Date1 end
if @Date2>@MostRecent begin set @MostRecent=@Date2 end
if @Date3>@MostRecent begin set @MostRecent=@Date3 end
RETURN @MostRecent
END
答案 18 :(得分:0)
使用 CASE WHEN
的另一种方法SELECT CASE true
WHEN max(row1) >= max(row2) THEN CASE true WHEN max(row1) >= max(row3) THEN max(row1) ELSE max(row3) end ELSE
CASE true WHEN max(row2) >= max(row3) THEN max(row2) ELSE max(row3) END END
FROM yourTable
答案 19 :(得分:0)
如果我想获取最大的ID,则有一个名为TblItem的表。我使用以下代码。
select MAX(Id) from TblItem
答案 20 :(得分:0)
我的解决方案也可以处理空值比较。可以通过编写单个查询来简化它,但为了解释,我使用的是 CTE。思路是将比较从步骤1中的3个数字减少到2个数字,然后在步骤2中从2个数字减少到1个数字。
with x1 as
(
select 1 as N1, null as N2, 3 as N3
union
select 1 as N1, null as N2, null as N3
union
select null as N1, null as N2, null as N3
)
,x2 as
(
select
N1,N2,N3,
IIF(Isnull(N1,0)>=Isnull(N2,0),N1,N2) as max1,
IIF(Isnull(N2,0)>=Isnull(N3,0),N2,N3) as max2
from x1
)
,x3 as
(
select N1,N2,N3,max1,max2,
IIF(IsNull(max1,0)>=IsNull(max2,0),max1,max2) as MaxNo
from x2
)
select * from x3
输出:
答案 21 :(得分:-2)
我不知道它是否在SQL上等...在M $ ACCESS帮助中有一个名为MAXA(Value1;Value2;...)
的函数应该这样做。
P.D。:值可以是列或计算值等。
答案 22 :(得分:-3)
这是一个很好的解决方案:
CREATE function [dbo].[inLineMax] (@v1 float,@v2 float,@v3 float,@v4 float)
returns float
as
begin
declare @val float
set @val = 0
declare @TableVal table
(value float )
insert into @TableVal select @v1
insert into @TableVal select @v2
insert into @TableVal select @v3
insert into @TableVal select @v4
select @val= max(value) from @TableVal
return @val
end
答案 23 :(得分:-3)
上表是一个以薪金1,薪金2,薪金3,薪金4为列的员工薪水表。下面的查询将返回四列中的最大值
select
(select Max(salval) from( values (max(salary1)),(max(salary2)),(max(salary3)),(max(Salary4)))alias(salval)) as largest_val
from EmployeeSalary
在上面的查询中运行时,输出将为largest_val(10001)
上述查询的逻辑如下:
select Max(salvalue) from(values (10001),(5098),(6070),(7500))alias(salvalue)
输出将为10001