Jawaban:
Nah, Anda bisa menggunakan pernyataan 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
[Untuk Microsoft SQL Server 2008 dan di atasnya, Anda dapat mempertimbangkan jawaban sederhana Sven di bawah ini.]
Berikut ini adalah solusi bagus untuk Max
fungsionalitas menggunakan T-SQL dan SQL Server
SELECT [Other Fields],
(SELECT Max(v)
FROM (VALUES (date1), (date2), (date3),...) AS value(v)) as [MaxDate]
FROM [YourTableName]
Jika Anda menggunakan MySQL, Anda bisa menggunakan
SELECT GREATEST(col1, col2 ...) FROM table
Ada 3 metode lagi di mana UNPIVOT
(1) adalah yang tercepat sejauh ini, diikuti oleh Simulated Unpivot (3) yang jauh lebih lambat daripada (1) tetapi masih lebih cepat dari (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
Salah satu dari dua sampel di bawah ini akan berfungsi:
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
Yang kedua adalah add-on untuk jawaban 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
Fungsi skalar menyebabkan segala macam masalah kinerja, jadi lebih baik untuk membungkus logika menjadi Fungsi Inline Table Valued jika memungkinkan. Ini adalah fungsi yang saya gunakan untuk mengganti beberapa Fungsi yang Ditentukan Pengguna yang memilih tanggal Min / Max dari daftar hingga sepuluh tanggal. Ketika diuji pada dataset saya dari 1 Juta baris, Fungsi Skalar memakan waktu lebih dari 15 menit sebelum saya membunuh permintaan, Inline TVF membutuhkan 1 menit yang merupakan jumlah waktu yang sama dengan memilih resultset ke dalam tabel sementara. Untuk menggunakan fungsi panggilan ini baik dari subquery di SELECT atau 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)
)
SELECT
CASE
WHEN Date1 >= Date2 AND Date1 >= Date3 THEN Date1
WHEN Date2 >= Date3 THEN Date2
ELSE Date3
END AS MostRecentDate
Ini sedikit lebih mudah untuk dituliskan dan dilewati langkah-langkah evaluasi karena pernyataan kasus dievaluasi secara berurutan.
Sayangnya jawaban Lasse , meskipun tampak jelas, memiliki kelemahan yang sangat penting. Itu tidak bisa menangani nilai NULL. Nilai NULL tunggal menghasilkan Date1 yang dikembalikan. Sayangnya setiap upaya untuk memperbaiki masalah itu cenderung menjadi sangat berantakan dan tidak skala ke 4 atau lebih nilai dengan sangat baik.
jawaban pertama databyss tampak (dan) bagus. Namun, tidak jelas apakah jawabannya akan dengan mudah mengekstrapolasi ke 3 nilai dari multi-tabel bergabung bukan 3 nilai sederhana dari satu tabel. Saya ingin menghindari mengubah query seperti itu menjadi sub-query hanya untuk mendapatkan maks 3 kolom, juga saya cukup yakin ide bagus databyss bisa dibersihkan sedikit.
Jadi tanpa basa-basi lagi, inilah solusi saya (berasal dari ide databyss).
Ini menggunakan cross-joins memilih konstanta untuk mensimulasikan efek multi-table join. Yang penting untuk dicatat adalah bahwa semua alias yang diperlukan dijalankan dengan benar (yang tidak selalu terjadi) dan ini membuat polanya cukup sederhana dan cukup skalabel melalui kolom tambahan.
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
Masalah: pilih nilai tarif minimum yang diberikan ke entitas Persyaratan: Tarif agensi bisa nol
[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
Terinspirasi oleh jawaban ini dari Nat
Jika Anda menggunakan SQL Server 2005, Anda dapat menggunakan fitur UNPIVOT. Ini adalah contoh lengkapnya:
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
Menggunakan CROSS APPLY (untuk 2005+) ....
SELECT MostRecentDate
FROM SourceTable
CROSS APPLY (SELECT MAX(d) MostRecentDate FROM (VALUES (Date1), (Date2), (Date3)) AS a(d)) md
Dari SQL Server 2012 kita bisa menggunakan 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
Saya lebih suka solusi berdasarkan kasus-kapan, asumsi saya adalah bahwa itu harus memiliki dampak paling kecil pada penurunan kinerja yang mungkin dibandingkan dengan solusi lain yang mungkin seperti yang berlaku silang, nilai (), fungsi kustom dll.
Ini adalah versi case-when yang menangani nilai null dengan sebagian besar kasus uji yang mungkin:
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
;
dan hasilnya adalah:
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
Anda dapat membuat fungsi di mana Anda melewati tanggal dan kemudian menambahkan fungsi ke pernyataan pilih seperti di bawah ini. pilih Nomor, dbo.fxMost_Recent_Date (Date1, Date2, Date3), Biaya
create FUNCTION fxMost_Recent_Date
(@ Date1 smalldatetime, @ Date2 smalldatetime, @ Date3 smalldatetime) RETURNS smalldatetime AS 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
AKHIR
Berdasarkan solusi ScottPletcher dari http://www.experts-exchange.com/Microsoft/Development/MS-SQL-Server/Q_24204894.html Saya telah membuat serangkaian fungsi (mis. GetMaxOfDates3, GetMaxOfDates13) untuk menemukan maks hingga 13 Nilai tanggal menggunakan UNION ALL. Lihat fungsi T-SQL untuk mendapatkan nilai maksimum dari baris yang sama. Namun saya belum mempertimbangkan solusi UNPIVOT pada saat penulisan fungsi-fungsi ini.
Tabel di atas adalah tabel gaji karyawan dengan gaji1, gaji2, gaji3, gaji4 sebagai kolom. Pertanyaan di bawah ini akan mengembalikan nilai maksimal dari empat kolom
select
(select Max(salval) from( values (max(salary1)),(max(salary2)),(max(salary3)),(max(Salary4)))alias(salval)) as largest_val
from EmployeeSalary
Menjalankan kueri di atas akan memberikan output sebagai terbesar_val (10001)
Logika kueri di atas adalah sebagai berikut:
select Max(salvalue) from(values (10001),(5098),(6070),(7500))alias(salvalue)
output akan menjadi 10001
ini solusi yang bagus:
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
Saya tidak tahu apakah itu di SQL, dll ... di M $ ACCESS membantu ada fungsi yang disebut MAXA(Value1;Value2;...)
yang seharusnya dilakukan.
Semoga bisa membantu seseorang.
PD: Nilai bisa berupa kolom atau yang dihitung, dll.
MAXA
adalah fungsi Excel , bukan Access.
WHEN Date1 > Date2 AND Date1 > Date3 THEN Date1; WHEN Date2 > Date3 THEN Date3; ELSE Date3
?