it-swarm-tr.com

Birden fazla fazla sütun SQL MAX?

Maksimum sütunun satır başına 1 değerini nasıl döndürürsünüz:

Tablo ismi

[Number, Date1, Date2, Date3, Cost]

Böyle bir şeyi iade etmem gerekiyor:

[Number, Most_Recent_Date, Cost]

Sorgu?

317
BenB

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 aşağıdaki daha basit cevabını düşünebilirsiniz.]

İşte T-SQL ve SQL Server kullanarak Max işlevselliği için başka bir Nice çözümü

SELECT [Other Fields],
  (SELECT Max(v) 
   FROM (VALUES (date1), (date2), (date3),...) AS value(v)) as [MaxDate]
FROM [YourTableName]
748
Sven

MySQL kullanıyorsanız, kullanabilirsiniz

SELECT GREATEST(col1, col2 ...) FROM table
111
bajafresh4life

UNPIVOT (1) 'in bugüne kadar en hızlı olduğu 3 yöntem daha var, ardından (1)' den çok daha yavaş fakat yine de (2) 'den daha hızlı olan Simulated 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

1. Çözüm (UNPIVOT)

SELECT  number ,
        MAX(dDate) maxDate ,
        cost
FROM    dates UNPIVOT ( dDate FOR nDate IN ( Date1, Date2,
                                            Date3 ) ) as u
GROUP BY number ,
        cost 
GO

2. Çözüm (Satır başına alt sorgu)

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

3. Çözüm (Simüle 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
57
Niikola

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's 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 
16
databyss

Skaler İşlev her türlü performans sorununa neden olur, bu nedenle mantığı mümkünse Satır İçi Tablo Değerli İşleve dahil etmek daha iyidir. Bu, Min/Maks tarihlerini en fazla on tarih listesinden 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ğinde, Skaler Fonksiyonu sorgusunu öldürmeden önce 15 dakika sürdü, Inline TVF 1 dakika sürdü, bu da sonuç setini geçici bir tabloya seçmekle aynı zamandı. Bu çağrıyı kullanmak için, SELECT seçeneğindeki bir alt sorgudan ya da bir CROSS APPLY'den fonksiyon çağırınız.

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)
)
9
MartinC
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
Martin Smith

T-SQL için (MSSQL 2008+)

SELECT
  (SELECT
     MAX(MyMaxName) 
   FROM ( VALUES 
            (MAX(iSortCode)), 
            (MAX(Field2)) 
        ) MyAlias(MyMaxName)
  ) 
FROM MyTable1
6
doker
SELECT 
    CASE 
        WHEN Date1 >= Date2 AND Date1 >= Date3 THEN Date1 
        WHEN Date2 >= Date3 THEN Date2 
        ELSE Date3
    END AS MostRecentDate 

Bu, durum bildirimi sırayla değerlendirilirken yazmak ve değerlendirme adımlarını atlamak biraz daha kolaydır.

5
Nat

Ne yazık ki Lasse'nin cevabı , görünüşte açık olmasına rağmen, çok önemli bir kusur var. NULL değerleri işleyemez. Herhangi bir tek NULL değeri, Date1 döndürülüyor. Ne yazık ki, bu sorunu çözme girişimi aşırı derecede dağınık olma eğilimindedir ve 4 veya daha fazla değeri çok iyi ölçeklendirmez.

veritabanlarının ilk cevabı baktı (ve iyi). Bununla birlikte, cevabın, tek bir tablodan daha basit 3 değerleri yerine, çoklu tablo birleşiminden 3 değere kolayca tahmin edilip edilemeyeceği açık değildi. En fazla 3 sütun alabilmek için böyle bir sorguyu alt sorguya çevirmekten kaçınmak istedim, ayrıca veri tabanının mükemmel fikrinin biraz temizlenebileceğinden de emindim.

Yani daha fazla uzatmadan, işte çözümüm (veri tabanının fikrinden türetilmiş).
Çok masalı birleştirmenin etkisini simüle etmek için sabitleri seçerek çapraz birleştirmeleri kullanır. Unutulmaması gereken önemli nokta, tüm gerekli takma adların doğru bir şekilde taşınmasıdır (bu her zaman böyle değildir) ve bu, kalıbı oldukça basit ve ek sütunlarla oldukça ölçeklenebilir hale getirir.

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
4
Disillusioned

Sorun: Bir işletmeye verilen minimum oran değerini seçin.

[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 

Bu cevaptan ilham alan dan Nat

4
Luis Miguel Rosa

CROSS APPLY'yi kullanma (2005+ için) ....

SELECT MostRecentDate 
FROM SourceTable
    CROSS APPLY (SELECT MAX(d) MostRecentDate FROM (VALUES (Date1), (Date2), (Date3)) AS a(d)) md
3
EarlOfEnnui

SQL Server 2012'den IIF kullanabilirsiniz.

 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
3
abdulbasit

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
3
Lance Fisher

Lütfen UNPIVOT kullanmayı deneyin:

SELECT MAX(MaxDt) MaxDt
   FROM tbl 
UNPIVOT
   (MaxDt FOR E IN 
      (Date1, Date2, Date3)
)AS unpvt;
1
TechDo

En büyük kimliği elde etmek istersem TblItem adlı bir masam var. Aşağıdaki kodu kullanıyorum.

select MAX(Id) from TblItem
0
Diako Hasani

Durum-zamana dayalı çözümleri tercih ediyorum, benim varsayım, çapraz uygulama, değerler (), özel fonksiyonlar vb. Gibi diğer olası çözümlerle karşılaştırıldığında olası performans düşüşü üzerinde en az etkiye sahip olması gerektiğidir.

İşte olası test durumlarının çoğuyla null değerleri işleyen case-when sürümü:

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
0
Robert Lujo

Kullanmanın başka bir yolu 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
0
M.A.Bell

ScottPletcher 'ın çözümüne göre http://www.experts-exchange.com/Microsoft/Development/MS-SQL-Server/Q_24204894.html .__' a göre bir set oluşturdum. UNION ALL ..__ kullanarak en fazla 13 tarih değeri bulmak için işlevlerin (örneğin GetMaxOfDates3, GetMaxOfDates13) .. .. Aynı satırdan maksimum değer elde etmek için T-SQL işlevine bakın Bu işlevleri yazarken UNPIVOT çözümü olarak kabul edildi 

0

Tarihleri ​​geçireceğiniz bir fonksiyon yaratabilir ve fonksiyonu aşağıdaki gibi select deyimine ekleyebilirsiniz. .. Sayı, dbo.fxMost_Recent_Date (Tarih1, Tarih2, Tarih3), Maliyet

create FUNCTION  fxMost_Recent_Date 

( @ @ Date1 smalldatetime, @ Date2 smalldatetime, @ Date3 smalldatetime ) RETURNS Instagram Hesabındaki Resim ve Videoları smalldatetime AS BEGIN DECLARE @Result smalldatetime

declare @MostRecent smalldatetime

set @MostRecent='1/1/1900'

if @Date1>@MostRecent begin set @[email protected] end
if @Date2>@MostRecent begin set @[email protected] end
if @Date3>@MostRecent begin set @[email protected] end
RETURN @MostRecent

SON

0
DrYodo