Yanıtlar:
CASE deyimini kullanabilirsiniz:
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 ve üstü için Sven'in daha basit cevabını aşağıda düşünebilirsiniz.]
İşte Max
T-SQL ve SQL Server kullanarak işlevsellik için güzel bir çözüm
SELECT [Other Fields],
(SELECT Max(v)
FROM (VALUES (date1), (date2), (date3),...) AS value(v)) as [MaxDate]
FROM [YourTableName]
MySQL kullanıyorsanız,
SELECT GREATEST(col1, col2 ...) FROM table
UNPIVOT
(1) 'in açık ara en hızlı olduğu 3 yöntem daha var , ardından (1)' den çok daha yavaş ancak (2) 'den daha hızlı olan Simüle Unpivot (3)
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
Aşağıdaki iki örnekten biri çalışacaktır:
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
İkincisi lassevk'in cevabına bir eklentidir .
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
Skaler İşlev her türlü performans sorununa neden olur, bu nedenle mantığı mümkünse Satır İçi Tablo Değerli İşlevine sarmak daha iyidir. Bu, en fazla on tarih listesinden Min / Maks tarihleri seçen bazı Kullanıcı Tanımlı İşlevleri değiştirmek için kullandığım işlevdir. 1 Milyon satırlık veri kümemde test edildiğimde, Skaler Fonksiyonu sorguyu öldürmeden önce 15 dakikadan fazla sürdü, Inline TVF, 1 dakika sürdü ve sonuç kümesini geçici bir tabloya seçmekle aynı süreydi. Bunu kullanmak için SELECT (SEÇ) veya CROSS UYGULAMASI altındaki bir alt sorgudan işlevi çağırın.
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
Bu durumun yazılması biraz daha kolaydır ve vaka ifadesi sırayla değerlendirilirken değerlendirme adımlarını atlar.
Ne yazık ki Lasse'nin cevabı , görünüşte açık olsa da, çok önemli bir kusura sahip. NULL değerleri işleyemez. Tek bir NULL değeri Date1 döndürülür. Ne yazık ki bu sorunu çözmek için yapılan herhangi bir girişim son derece dağınık olma eğilimindedir ve 4 veya daha fazla değere çok iyi ölçeklenmez.
databyss'ın ilk cevabı iyi görünüyordu (ve iyi). Ancak, cevabın tek bir tablodan daha basit 3 değerler yerine çok masalı birleştirmeden 3 değere kolayca tahmin edilip edilmeyeceği açık değildi. Sadece en fazla 3 sütun almak için bir alt sorguya böyle bir sorgu açmaktan kaçınmak istedim, aynı zamanda databyss mükemmel fikir biraz temizlenebilir eminim.
Daha fazla uzatmadan, benim çözümüm (veritabanlarının fikrinden türetilmiş).
Çok masalı birleştirmenin etkisini simüle etmek için sabit birleşimleri seçerek sabitleri kullanır. Dikkat edilmesi gereken önemli olan, tüm gerekli takma adların doğru bir şekilde taşınmasıdır (her zaman böyle değildir) ve bu, kalıbı ek sütunlarla oldukça basit ve oldukça ölçeklenebilir tutar.
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
Sorun: Bir işletmeye verilen minimum ücret değerini seçin Gereksinimler: Ajans ücretleri boş olabilir
[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
SQL Server 2005 kullanıyorsanız, UNPIVOT özelliğini kullanabilirsiniz. İşte tam bir örnek:
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
ÇAPRAZ UYGULAYI Kullanma (2005+ için) ....
SELECT MostRecentDate
FROM SourceTable
CROSS APPLY (SELECT MAX(d) MostRecentDate FROM (VALUES (Date1), (Date2), (Date3)) AS a(d)) md
SQL Server 2012'den IIF kullanabiliriz .
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
Ben duruma göre çözümleri tercih ederim, benim varsayım, çapraz uygulama, değerler (), özel işlevler vb.
Aşağıda, olası test durumlarının çoğuyla null değerleri işleyen case-when sürümü verilmiştir:
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
;
ve sonuç:
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
Tarihleri ilettiğiniz bir işlevi oluşturabilir ve sonra işlevi aşağıdaki gibi select deyimine ekleyebilirsiniz. Sayı, dbo.fxMost_Recent_Date (Tarih1, Tarih2, Tarih3), Maliyet'i seçin
create FUNCTION fxMost_Recent_Date
(@ Tarih1 smalldatetime, @ Tarih2 smalldatetime, @ Tarih3 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
SON
ScottPletcher'ın http://www.experts-exchange.com/Microsoft/Development/MS-SQL-Server/Q_24204894.html adresindeki çözümüne dayanarak maks. Bulmak için bir dizi işlev oluşturdum (örn. UNION ALL kullanılarak 13 Tarih değerine kadar. Aynı satırdan maksimum değer almak için T-SQL işlevine bakın. Ancak bu işlevleri yazarken UNPIVOT çözümünü dikkate almadım
Yukarıdaki tablo, maaş1, maaş2, maaş3, maaş4 sütunları olan bir çalışan maaş tablosudur.Aşağıdaki sorgu, dört sütundan maksimum değeri döndürür
select
(select Max(salval) from( values (max(salary1)),(max(salary2)),(max(salary3)),(max(Salary4)))alias(salval)) as largest_val
from EmployeeSalary
Sorgunun üstünde çalıştırıldığında çıktı en büyük_değer (10001) olarak verilir
Yukarıdaki sorgu mantığı aşağıdaki gibidir:
select Max(salvalue) from(values (10001),(5098),(6070),(7500))alias(salvalue)
çıktı 10001 olacak
İşte iyi bir çözüm:
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
SQL, vb olup olmadığını bilmiyorum ... M $ ACCESS yardım üzerinde bir fonksiyon var MAXA(Value1;Value2;...)
böyle yapması gerekiyordu .
Umut birine yardım edebilir.
PD: Değerler sütunlar veya hesaplananlar vb. Olabilir.
MAXA
Access değil bir Excel işlevidir .
WHEN Date1 > Date2 AND Date1 > Date3 THEN Date1; WHEN Date2 > Date3 THEN Date3; ELSE Date3
mı?