Ben*_*enB 343 sql t-sql sql-server
如何在每行最多的几列中返回1个值:
表名
[Number, Date1, Date2, Date3, Cost]
Run Code Online (Sandbox Code Playgroud)
我需要返回这样的东西:
[Number, Most_Recent_Date, Cost]
Run Code Online (Sandbox Code Playgroud)
查询?
Sve*_*ven 809
这是Max使用T-SQL和SQL Server的另一个很好的解决方案
SELECT [Other Fields],
(SELECT Max(v)
FROM (VALUES (date1), (date2), (date3),...) AS value(v)) as [MaxDate]
FROM [YourTableName]
Run Code Online (Sandbox Code Playgroud)
ang*_*son 153
好吧,你可以使用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
Run Code Online (Sandbox Code Playgroud)
[对于Microsoft SQL Server 2008及更高版本,您可以考虑下面的Sven更简单的答案.
baj*_*ife 132
如果您使用的是MySQL,则可以使用
SELECT GREATEST(col1, col2 ...) FROM table
Run Code Online (Sandbox Code Playgroud)
Nii*_*ola 62
还有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
Run Code Online (Sandbox Code Playgroud)
UNPIVOT)SELECT number ,
MAX(dDate) maxDate ,
cost
FROM dates UNPIVOT ( dDate FOR nDate IN ( Date1, Date2,
Date3 ) ) as u
GROUP BY number ,
cost
GO
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
dat*_*yss 17
以下两个样本中的任何一个都可以使用:
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
Run Code Online (Sandbox Code Playgroud)
第二个是对lassevk答案的补充.
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
Run Code Online (Sandbox Code Playgroud)
dok*_*ker 13
对于T-SQL(MSSQL 2008+)
SELECT
(SELECT
MAX(MyMaxName)
FROM ( VALUES
(MAX(Field1)),
(MAX(Field2))
) MyAlias(MyMaxName)
)
FROM MyTable1
Run Code Online (Sandbox Code Playgroud)
小智 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)
)
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
SELECT
CASE
WHEN Date1 >= Date2 AND Date1 >= Date3 THEN Date1
WHEN Date2 >= Date3 THEN Date2
ELSE Date3
END AS MostRecentDate
Run Code Online (Sandbox Code Playgroud)
在按顺序评估案例陈述时,这更容易写出并略过评估步骤.
不幸的是,Lasse 的回答虽然看起来很明显,但有一个关键的缺陷。它无法处理 NULL 值。任何单个 NULL 值都会导致 Date1 被返回。不幸的是,任何解决该问题的尝试都会变得非常混乱,并且不能很好地扩展到 4 个或更多值。
databyss 的第一个答案看起来(而且现在)很好。但是,不清楚该答案是否可以轻松地从多表连接中推断出 3 个值,而不是从单个表中推断出更简单的 3 个值。我想避免将这样的查询转换为子查询以获得最多 3 列,而且我很确定 databyss 的好主意可以稍微清理一下。
所以不用多说,这是我的解决方案(源自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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
477305 次 |
| 最近记录: |