Câu trả lời:
Chà, bạn có thể sử dụng câu lệnh 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
[Đối với Microsoft SQL Server 2008 trở lên, bạn có thể xem xét câu trả lời đơn giản hơn của Sven bên dưới.]
Đây là một giải pháp hay khác cho Max
chức năng sử dụng T-SQL và SQL Server
SELECT [Other Fields],
(SELECT Max(v)
FROM (VALUES (date1), (date2), (date3),...) AS value(v)) as [MaxDate]
FROM [YourTableName]
Nếu bạn đang sử dụng MySQL, bạn có thể sử dụng
SELECT GREATEST(col1, col2 ...) FROM table
Có thêm 3 phương thức trong đó UNPIVOT
(1) là nhanh nhất cho đến nay, tiếp theo là Mô phỏng không xoay vòng (3) chậm hơn nhiều so với (1) nhưng vẫn nhanh hơn (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
Một trong hai mẫu dưới đây sẽ hoạt động:
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
Thứ hai là phần bổ trợ cho câu trả lời của 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
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
Hàm vô hướng gây ra tất cả các loại vấn đề về hiệu năng, vì vậy tốt hơn hết là bọc logic vào Hàm nội tuyến có giá trị nếu có thể. Đây là chức năng tôi đã sử dụng để thay thế một số Hàm do người dùng xác định đã chọn ngày tối thiểu / tối đa từ danh sách tối đa mười ngày. Khi được kiểm tra trên tập dữ liệu 1 triệu hàng của tôi, Hàm vô hướng mất hơn 15 phút trước khi tôi hủy truy vấn, TVF nội tuyến mất 1 phút, cùng thời gian với việc chọn kết quả vào bảng tạm thời. Để sử dụng lệnh này, hãy gọi hàm từ một truy vấn con trong CHỌN hoặc ỨNG DỤNG CROSS.
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)
)
SELECT
CASE
WHEN Date1 >= Date2 AND Date1 >= Date3 THEN Date1
WHEN Date2 >= Date3 THEN Date2
ELSE Date3
END AS MostRecentDate
Điều này hơi dễ viết ra và bỏ qua các bước đánh giá vì tuyên bố trường hợp được đánh giá theo thứ tự.
Thật không may , câu trả lời của Lasse , mặc dù có vẻ rõ ràng, có một lỗ hổng quan trọng. Nó không thể xử lý các giá trị NULL. Bất kỳ giá trị NULL duy nhất nào dẫn đến Date1 được trả về. Thật không may, bất kỳ nỗ lực nào để khắc phục vấn đề đó có xu hướng trở nên cực kỳ lộn xộn và không quy mô thành 4 hoặc nhiều giá trị rất độc đáo.
Câu trả lời đầu tiên của databyss nhìn (và là) tốt. Tuy nhiên, không rõ liệu câu trả lời có dễ dàng ngoại suy thành 3 giá trị từ phép nối nhiều bảng thay vì 3 giá trị đơn giản hơn từ một bảng không. Tôi muốn tránh biến một truy vấn như vậy thành truy vấn phụ chỉ để có tối đa 3 cột, tôi cũng khá chắc chắn rằng ý tưởng tuyệt vời của databyss có thể được làm sạch một chút.
Vì vậy, không có gì khó chịu, đây là giải pháp của tôi (xuất phát từ ý tưởng của databyss).
Nó sử dụng các phép nối chéo chọn các hằng số để mô phỏng hiệu ứng của phép nối nhiều bảng. Điều quan trọng cần lưu ý là tất cả các bí danh cần thiết đều thực hiện chính xác (điều này không phải luôn luôn như vậy) và điều này giữ cho mẫu khá đơn giản và có thể mở rộng khá thông qua các cột bổ sung.
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
Vấn đề: chọn giá trị tỷ lệ tối thiểu được cung cấp cho một thực thể Yêu cầu: Tỷ lệ đại lý có thể là null
[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
Lấy cảm hứng từ câu trả lời này từ Nat
Nếu bạn đang sử dụng SQL Server 2005, bạn có thể sử dụng tính năng UNPIVOT. Dưới đây là một ví dụ hoàn chỉnh:
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
Sử dụng CROSS ỨNG DỤNG (cho năm 2005 trở lên) ....
SELECT MostRecentDate
FROM SourceTable
CROSS APPLY (SELECT MAX(d) MostRecentDate FROM (VALUES (Date1), (Date2), (Date3)) AS a(d)) md
Từ SQL Server 2012, chúng ta có thể sử dụng 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
DECLARE @Date1 DATE='2014-08-01'; DECLARE @Date2 DATE=null; DECLARE @Date3 DATE='2014-07-05'; /*this gets returned*/
select IIF(@Date1 > @Date2 or @Date2 is null, IIF(@Date1 > @Date3 or @Date3 is null, @Date1, @Date3), IIF(@Date2 > @Date3 or @Date3 is null, @Date2, @Date3)) as MostRecentDate
Tôi thích các giải pháp dựa trên trường hợp khi, giả định của tôi là nó sẽ có tác động ít nhất đến việc giảm hiệu suất có thể so với các giải pháp có thể khác như các giải pháp áp dụng chéo, giá trị (), hàm tùy chỉnh, v.v.
Đây là phiên bản case-when xử lý các giá trị null với hầu hết các trường hợp thử nghiệm có thể:
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
;
và kết quả là:
MostRecent id Date1 Date2 Date3
2003-01-01 1 2001-01-01 2002-01-01 2003-01-01
2003-01-01 2 2001-01-01 2003-01-01 2002-01-01
2003-01-01 3 2002-01-01 2001-01-01 2002-01-01
2003-01-01 4 2002-01-01 2003-01-01 2001-01-01
2003-01-01 5 2003-01-01 2001-01-01 2002-01-01
2003-01-01 6 2003-01-01 2002-01-01 2001-01-01
2003-01-01 11 NULL 2002-01-01 2003-01-01
2003-01-01 12 NULL 2003-01-01 2002-01-01
2003-01-01 13 2003-01-01 NULL 2002-01-01
2003-01-01 14 2002-01-01 NULL 2003-01-01
2003-01-01 15 2003-01-01 2002-01-01 NULL
2003-01-01 16 2002-01-01 2003-01-01 NULL
2003-01-01 21 2003-01-01 NULL NULL
2003-01-01 22 NULL 2003-01-01 NULL
2003-01-01 23 NULL NULL 2003-01-01
NULL 31 NULL NULL NULL
Bạn có thể tạo một hàm trong đó bạn vượt qua ngày và sau đó thêm hàm vào câu lệnh chọn như bên dưới. chọn Số, dbo.fxMost_Recent_Date (Ngày 1, Ngày 2, Ngày 3), Chi phí
create FUNCTION fxMost_Recent_Date
(@ Date1 smalldatetime, @ Date2 smalldatetime, @ Date3 smalldatetime) TRẢ LẠI thời gian nhỏ NHƯ BEGIN 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
KẾT THÚC
Dựa trên giải pháp của ScottPletcher từ http://www.experts-exchange.com/Microsoft/Development/MS-Query-Server/Q_24204894.html Tôi đã tạo một tập hợp các hàm (ví dụ: GetMaxOfDates3, GetMaxOfDates13) tối đa 13 giá trị Ngày sử dụng UNION ALL. Xem hàm T-SQL để lấy tối đa các giá trị từ cùng một hàng Tuy nhiên tôi chưa xem xét giải pháp UNPIVOT tại thời điểm viết các hàm này
Bảng trên là bảng lương nhân viên với mức lương1, tiền lương 2, tiền lương 3, tiền lương4 dưới dạng cột. Câu hỏi dưới đây sẽ trả về giá trị tối đa trong bốn cột
select
(select Max(salval) from( values (max(salary1)),(max(salary2)),(max(salary3)),(max(Salary4)))alias(salval)) as largest_val
from EmployeeSalary
Chạy truy vấn trên sẽ cho đầu ra là lớn nhất (10001)
Logic của truy vấn trên là như sau:
select Max(salvalue) from(values (10001),(5098),(6070),(7500))alias(salvalue)
đầu ra sẽ là 10001
Đây là một giải pháp tốt:
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
Tôi không biết nếu nó có trên SQL, v.v ... trên trợ giúp M $ ACCESS có một chức năng được gọi MAXA(Value1;Value2;...)
là phải làm như vậy.
Hy vọng có thể giúp ai đó.
PD: Giá trị có thể là cột hoặc tính toán, v.v.
MAXA
là một hàm Excel , không phải Access.
WHEN Date1 > Date2 AND Date1 > Date3 THEN Date1; WHEN Date2 > Date3 THEN Date3; ELSE Date3
?