Apakah ada fungsi Max di SQL Server yang mengambil dua nilai seperti Math.Max ​​di .NET?

488

Saya ingin menulis kueri seperti ini:

SELECT o.OrderId, MAX(o.NegotiatedPrice, o.SuggestedPrice)
FROM Order o

Tapi ini bukan bagaimana MAXfungsinya bekerja, kan? Ini adalah fungsi agregat sehingga mengharapkan satu parameter dan kemudian mengembalikan MAX dari semua baris.

Adakah yang tahu cara melakukannya dengan cara saya?

skb
sumber
13
Itu diimplementasikan di sebagian besar database lain sebagai GREATESTfungsi; SQLite mengemulasi dukungan dengan memungkinkan beberapa kolom dalam MAXagregat.
OMG Ponies
7
Kemungkinan duplikat stackoverflow.com/questions/71022/sql-max-of-multiple-columns
Michael Freidgeim
Ketika menemukan solusi untuk maks (a, b) di bawah, ingat pertanyaan tentang apakah Anda ingin sintaks atau perhitungan untuk "a" dan / atau "b" diulang. Yaitu jika "b" berasal dari perhitungan kompleks yang melibatkan banyak sintaks maka Anda dapat memilih solusi di mana "b" hanya muncul sekali. Misalnya solusi "IIF (a> b, a, b)" berarti mengulangi "b" - yang mungkin secara sintaksis jelek, namun solusi berikut ini berarti "b" (dan "a") hanya muncul sekali: SELECT MAX (VALUE) DARI (PILIH UNION NILAI SELECT SEBAGAI NILAI NILAI) SEBAGAI T1
Andrew Jens

Jawaban:

158

Anda perlu membuat User-Defined Functionjika Anda ingin memiliki sintaksis yang mirip dengan contoh Anda, tetapi bisakah Anda melakukan apa yang ingin Anda lakukan, sebaris, dengan cukup mudah dengan CASEpernyataan, seperti yang dikatakan orang lain.

The UDFbisa menjadi sesuatu seperti ini:

create function dbo.InlineMax(@val1 int, @val2 int)
returns int
as
begin
  if @val1 > @val2
    return @val1
  return isnull(@val2,@val1)
end

... dan Anda akan menyebutnya seperti itu ...

SELECT o.OrderId, dbo.InlineMax(o.NegotiatedPrice, o.SuggestedPrice) 
FROM Order o
Kevin Crumley
sumber
25
Saya akan mendukung solusi Anda, satu-satunya hal yang saya tambahkan adalah dukungan untuk nilai NULL. Jika Anda hanya memodifikasi baris terakhir: "return @ value2" untuk dibaca sebagai: "return isnull (@ val2, @ val1)" maka jika salah satu dari nilai-nilai itu null, fungsi akan mengembalikan nilai yang bukan nol, jika tidak maka akan berfungsi sebagai normal
kristof
1
Bagaimana dengan tipe data lainnya, misalnya, apakah saya perlu menulis HigherIntegerArgument dan HigherDateTimeArgument dan HigherVarcharArgument dan ...?
onedaywhen
9
ini akan sangat lambat, karena semua hal skalar UDF. Gunakan UDF inline sebagai gantinya
AK
12
@xan Saya tidak tahu apa yang terlintas dalam pikiran saya ketika saya benar-benar mengajukan pertanyaan itu. Jelas tidak terlalu banyak. Terima kasih atas jawabannya.
Thomas
13
@Thomas Wajib meme image (jangan ada pelanggaran yang ditujukan kepada Anda dengan cara apa pun!) Flickr.com/photos/16201371@N00/2375571206
xan
468

Jika Anda menggunakan SQL Server 2008 (atau lebih tinggi), maka ini adalah solusi yang lebih baik:

SELECT o.OrderId,
       (SELECT MAX(Price)
        FROM (VALUES (o.NegotiatedPrice),(o.SuggestedPrice)) AS AllPrices(Price))
FROM Order o

Semua kredit dan suara harus masuk ke jawaban Sven untuk pertanyaan terkait, "SQL MAX dari banyak kolom?"
Saya mengatakan itu adalah " jawaban terbaik " karena:

  1. Tidak perlu mempersulit kode Anda dengan UNION, PIVOT, UNPIVOT, UDF, dan statemen KASUS yang gila.
  2. Itu tidak terganggu dengan masalah penanganan nulls, itu menangani mereka dengan baik.
  3. Sangat mudah untuk menukar "MAX" dengan "MIN", "AVG", atau "SUM". Anda dapat menggunakan fungsi agregat apa saja untuk menemukan agregat di atas banyak kolom berbeda.
  4. Anda tidak terbatas pada nama yang saya gunakan (yaitu "AllPrices" dan "Price"). Anda dapat memilih nama Anda sendiri untuk membuatnya lebih mudah dibaca dan dimengerti untuk pria berikutnya.
  5. Anda dapat menemukan beberapa agregat menggunakan SQL Server 2008 yang dapat diturunkan seperti:
    SELECT MAX (a), MAX (b) FROM (VALUES (1, 2), (3, 4), (5, 6), (5, 6), (7, 8), (9, 10)) SEBAGAI MyTable (a, b)
MikeTeeVee
sumber
27
+1 hanya jawaban yang tidak memerlukan akses untuk membuat prosedur / fungsi!
Alex
6
Jenis jawaban yang saya cari. Menggunakan fungsi lambat dan ini juga akan berfungsi pada tanggal, yang saya butuhkan.
Johann Strydom
3
+1 Berfungsi sempurna, terutama untuk lebih dari 2 kolom yang akan dibandingkan!
JanW
11
Ini kurang berkinerja daripada solusi KASUS KETIKA yang hanya perlu menghitung skalar.
tekumara
5
Meskipun sintaks yang lebih sederhana mungkin tidak pernah sepadan dengan performa yang dicapai saat menentukan nilai MAX dari 2, itu mungkin masalah yang berbeda dengan nilai yang lebih banyak. Bahkan ketika mendapatkan nilai MAX 4, klausa KASUS menjadi panjang, kikuk dan rawan kesalahan jika dihasilkan secara manual sementara klausa VALUES tetap sederhana dan jelas.
Typhlosaurus
221

Dapat dilakukan dalam satu baris:

-- the following expression calculates ==> max(@val1, @val2)
SELECT 0.5 * ((@val1 + @val2) + ABS(@val1 - @val2)) 

Sunting: Jika Anda berurusan dengan angka yang sangat besar, Anda harus mengubah variabel nilai menjadi bigint untuk menghindari overflow integer.

percikan
sumber
18
+1 Saya yakin Anda telah memberikan cara yang paling benar. "SELECT ((@ val1 + @ val2) + ABS (@ val1- @ val2)) / 2 sebagai MAX_OF_TWO" Juga ingat, "SELECT ((@ val1 + @ val2) - ABS (@ val1- @ val2)) / 2 sebagai MIN_OF_TWO ".
tom
6
Cara ini akan memberikan kesalahan overflow jika jumlahnya lebih besar dari yang dapat disimpan dalam int: menyatakan @ val1 int menyatakan @ val2 int set @ val1 = 1500000000 set @ val2 = 1500000000 PILIH 0,5 * ((@ val1 + @ val2) + ABS (@ val1 - @ val2)) - => error overflow
AakashM
89
Ini sangat "kotor" "trik". Ketika memprogram kode Anda harus secara eksplisit menyatakan tujuannya, namun dalam kasus Anda sepertinya kode itu diambil dari kontes kebingungan.
greenoldman
24
Ini mungkin "kotor", tetapi bisa menjadi satu-satunya pilihan untuk database dengan dialek SQL sederhana.
splattne
12
Saya tidak setuju dengan marcias. Kode tidak harus dengan sendirinya menyatakan tujuan secara eksplisit, selama komentar memungkinkan seseorang untuk menyelesaikannya. Jika Anda melakukan persamaan matematika yang rumit dalam kode (atau di mana saja) kadang-kadang agak sulit untuk membuatnya sendiri deskriptif. Selama itu dipecah menjadi lebih sederhana, lebih mudah untuk memahami bagian maka itu pemrograman yang benar.
Rob
127

Saya kira tidak. Saya menginginkan ini tempo hari. Yang paling dekat yang saya dapatkan adalah:

SELECT
  o.OrderId,
  CASE WHEN o.NegotiatedPrice > o.SuggestedPrice THEN o.NegotiatedPrice 
     ELSE o.SuggestedPrice
  END
FROM Order o
Scott Langham
sumber
4
Ini adalah metode favorit saya. Anda tidak mengambil risiko overflow, dan itu kurang samar daripada solusi splattne (yang keren btw), dan saya tidak memiliki kerumitan membuat UDF. kasing sangat berguna dalam banyak situasi.
Lance Fisher
PILIH o.OrderId, KASUS SAAT o.NegosiasiHarga> o.DisarankanHarga ATAU o. DisarankanHARGA NULL KEMUDIAN o. DinegosiasikanHARGA LAIN o. DisarankanHarga AKHIR DARI DARI Pesanan o
mohghaderi
Ketika alih-alih "o.NegotiatedHarga" Anda memiliki istilah seperti "(Dateiff (hari, konversikan (datetime, adr_known_since, 120), getdate ()) - 5) * 0,3" Anda harus mengulangi kode ini. Setiap perubahan masa depan pada istilah tersebut harus dilakukan dua kali. Fungsi tipe min (x, y, ...) akan jauh lebih baik
Daniel
87

Mengapa tidak mencoba fungsi IIF (memerlukan SQL Server 2012 dan yang lebih baru)

IIF(a>b, a, b)

Itu dia.

(Petunjuk: berhati-hatilah terhadap keduanya null, karena hasilnya a>bakan salah setiap kali nol. Jadi bakan menjadi hasil dalam kasus ini)

Xin
sumber
7
Jika salah satu nilainya NULL, hasilnya akan selalu menjadi yang kedua.
jahu
4
IIF () adalah gula sintaksis untuk pernyataan CASE. Jika salah satu nilai kondisi CASE adalah NULL, hasilnya akan menjadi yang kedua (ELSE).
xxyzzy
@xxyzzy itu karena NULL > 1234pernyataan salah
Xin
8
jadi IIF(a>b, a, COALESCE(b,a))untuk memberikan nilai ketika hanya ada satu
mpag
32
DECLARE @MAX INT
@MAX = (SELECT MAX(VALUE) 
               FROM (SELECT 1 AS VALUE UNION 
                     SELECT 2 AS VALUE) AS T1)
terima kasih
sumber
Saya memberikan solusi ini +1 karena sesuai dengan KERING (jangan ulangi sendiri) tanpa perlu menulis UDF. Ini juga bagus jika kedua nilai yang Anda perlu periksa adalah hasil dari sql lain, misalnya dalam kasus saya, saya ingin menemukan lebih besar dari 2 pernyataan hitung pilih (*).
MikeKulls
1
Saya benci bahwa saya harus menggunakan solusi ini, tetapi sudah pasti cara terbaik untuk melakukannya di SQL Server sampai mereka menambahkan dukungan asli untuk GREATEST atau in-line MAX. Terima kasih telah mempostingnya - +1 untuk Anda!
SqlRyan
10

Jawaban lainnya bagus, tetapi jika Anda harus khawatir memiliki nilai NULL, Anda mungkin menginginkan varian ini:

SELECT o.OrderId, 
   CASE WHEN ISNULL(o.NegotiatedPrice, o.SuggestedPrice) > ISNULL(o.SuggestedPrice, o.NegotiatedPrice)
        THEN ISNULL(o.NegotiatedPrice, o.SuggestedPrice)
        ELSE ISNULL(o.SuggestedPrice, o.NegotiatedPrice)
   END
FROM Order o

sumber
1
Satu-satunya ISNULL yang diperlukan adalah setelah ELSE. Perbandingan ">" awal akan mengembalikan false dan pergi ke ELSE jika salah satu dari nilai sudah nol.
Phil B
10

Di SQL Server 2012 atau lebih tinggi, Anda bisa menggunakan kombinasi dari IIFdan ISNULL(atau COALESCE) untuk mendapatkan maksimum 2 nilai.
Bahkan ketika 1 dari mereka adalah NULL.

IIF(col1 >= col2, col1, ISNULL(col2, col1)) 

Atau jika Anda ingin mengembalikan 0 ketika keduanya NULL

IIF(col1 >= col2, col1, COALESCE(col2, col1, 0)) 

Cuplikan contoh:

-- use table variable for testing purposes
declare @Order table 
(
  OrderId int primary key identity(1,1),
  NegotiatedPrice decimal(10,2),
  SuggestedPrice decimal(10,2)
);

-- Sample data
insert into @Order (NegotiatedPrice, SuggestedPrice) values
(0, 1),
(2, 1),
(3, null),
(null, 4);

-- Query
SELECT 
     o.OrderId, o.NegotiatedPrice, o.SuggestedPrice, 
     IIF(o.NegotiatedPrice >= o.SuggestedPrice, o.NegotiatedPrice, ISNULL(o.SuggestedPrice, o.NegotiatedPrice)) AS MaxPrice
FROM @Order o

Hasil:

OrderId NegotiatedPrice SuggestedPrice  MaxPrice
1       0,00            1,00            1,00
2       2,00            1,00            2,00
3       3,00            NULL            3,00
4       NULL            4,00            4,00

Tetapi jika seseorang perlu SUM beberapa nilai?
Kemudian saya sarankan untuk SALIN BERLAKU ke agregasi dari NILAI.
Ini juga memiliki manfaat bahwa ini dapat menghitung hal-hal lain pada saat yang bersamaan.

Contoh:

SELECT t.*
, ca.[Total]
, ca.[Maximum]
, ca.[Minimum]
, ca.[Average]
FROM SomeTable t
CROSS APPLY (
   SELECT 
    SUM(v.col) AS [Total], 
    MIN(v.col) AS [Minimum], 
    MAX(v.col) AS [Maximum], 
    AVG(v.col) AS [Average]
   FROM (VALUES (t.Col1), (t.Col2), (t.Col3), (t.Col4)) v(col)
) ca
LukStorms
sumber
8

Sub Kueri dapat mengakses kolom dari kueri Luar sehingga Anda dapat menggunakan pendekatan ini untuk menggunakan agregat seperti MAXlintas kolom. (Mungkin lebih bermanfaat ketika ada lebih banyak kolom yang terlibat)

;WITH [Order] AS
(
SELECT 1 AS OrderId, 100 AS NegotiatedPrice, 110 AS SuggestedPrice UNION ALL
SELECT 2 AS OrderId, 1000 AS NegotiatedPrice, 50 AS SuggestedPrice
)
SELECT
       o.OrderId, 
       (SELECT MAX(price)FROM 
           (SELECT o.NegotiatedPrice AS price 
            UNION ALL SELECT o.SuggestedPrice) d) 
        AS MaxPrice 
FROM  [Order]  o
Martin Smith
sumber
Bagus! Ini berskala sangat baik.
greenoldman
+1 untuk menunjukkan Cinta untuk mereka yang masih di tahun 2005. Saya tidak tahu bagaimana saya mengabaikan jawaban ini. Di bawah selimut, saya membayangkan itu melakukan sama baiknya dengan apa yang saya posting 2-tahun kemudian. Dalam retrospeksi, saya seharusnya menyadari ini dan memperbarui jawaban Anda untuk memasukkan sintaks 2008 yang lebih baru pada saat itu. Maaf, berharap saya bisa membagikan poin saya dengan Anda sekarang.
MikeTeeVee
@MikeTeeVee - Terima kasih! Ya di bawah sampul rencananya akan sama. Tetapi VALUESsintaksisnya lebih bagus.
Martin Smith
6

SQL Server 2012 memperkenalkan IIF:

SELECT 
    o.OrderId, 
    IIF( ISNULL( o.NegotiatedPrice, 0 ) > ISNULL( o.SuggestedPrice, 0 ),
         o.NegotiatedPrice, 
         o.SuggestedPrice 
    )
FROM 
    Order o

Menangani NULL disarankan saat menggunakan IIF, karena a NULLdi kedua sisi Anda boolean_expressionakan menyebabkan IIFpengembalian false_value(sebagai lawan dari NULL).

SetFreeByTruth
sumber
Solusi Anda tidak akan menangani NULL dengan baik ketika nilai lainnya negatif, ini akan mengembalikan null
t-clausen.dk
5

Saya akan pergi dengan solusi yang disediakan oleh kcrumley Hanya memodifikasinya sedikit untuk menangani NULLs

create function dbo.HigherArgumentOrNull(@val1 int, @val2 int)
returns int
as
begin
  if @val1 >= @val2
    return @val1
  if @val1 < @val2
    return @val2

 return NULL
end

EDIT Dimodifikasi setelah komentar dari Mark . Seperti yang ditunjukkannya dengan benar dalam 3 logika bernilai x> NULL atau x <NULL harus selalu mengembalikan NULL. Dengan kata lain hasil yang tidak diketahui.

kristof
sumber
1
Null itu penting. Dan penting untuk menanganinya secara konsisten. Satu-satunya jawaban yang tepat untuk Is NULL> x adalah NULL.
Mark Brackett
Anda benar, saya akan mengubah jawaban saya untuk mencerminkan itu, terima kasih untuk menunjukkannya
kristof
Jika kita melewatkan int dan NULL maka saya pikir itu lebih umum untuk menginginkan nilai non-null dikembalikan, jadi fungsinya bertindak sebagai kombinasi Max (x, y) dan ISNULL (x, y). Oleh karena itu saya pribadi akan mengubah baris terakhir menjadi: kembali ISNULL (@ VAL1, @ VAL2) - yang diakui mungkin apa yang Anda harus mulai dengan :)
redcalx
@ the-locster, lihat komentar oleh Mark
kristof
1
ini akan sangat lambat, karena semua hal skalar UDF. Gunakan UDF inline sebagai gantinya
AK
4

Sesederhana ini:

CREATE FUNCTION InlineMax
(
    @p1 sql_variant,
    @p2 sql_variant
)  RETURNS sql_variant
AS
BEGIN
    RETURN CASE 
        WHEN @p1 IS NULL AND @p2 IS NOT NULL THEN @p2 
        WHEN @p2 IS NULL AND @p1 IS NOT NULL THEN @p1
        WHEN @p1 > @p2 THEN @p1
        ELSE @p2 END
END;
Uri Abramson
sumber
Lihat @Neil komentar ke jawaban SELECT dbo.InlineMax sebelumnya (CAST (0,5 AS FLOAT), 100) salah.
Luca
4
SELECT o.OrderId,   
--MAX(o.NegotiatedPrice, o.SuggestedPrice)  
(SELECT MAX(v) FROM (VALUES (o.NegotiatedPrice), (o.SuggestedPrice)) AS value(v)) as ChoosenPrice  
FROM Order o
Tom Arleth
sumber
Untuk penjelasan, silakan baca artikel ini: red-gate.com/simple-talk/sql/sql-training/…
Tom Arleth
2
Harap jangan sertakan informasi yang diperlukan ke kode Anda hanya dengan tautan. Bayangkan bahwa tautan ini akan kedaluwarsa pada suatu hari dan jawaban Anda akan sia-sia. Jadi silakan lanjutkan dan tambahkan informasi essentiell langsung dalam jawaban Anda. Tetapi Anda masih dapat memberikan tautan itu sebagai sumber daya bagi orang lain untuk mencari informasi lebih lanjut.
L. Guthardt
3

Ups, saya baru saja mengirim duplikat dari pertanyaan ini ...

Jawabannya adalah, tidak ada fungsi bawaan seperti Oracle's Greatest , tetapi Anda dapat mencapai hasil yang sama untuk 2 kolom dengan UDF, perhatikan, penggunaan sql_variant cukup penting di sini.

create table #t (a int, b int) 

insert #t
select 1,2 union all 
select 3,4 union all
select 5,2

-- option 1 - A case statement
select case when a > b then a else b end
from #t

-- option 2 - A union statement 
select a from #t where a >= b 
union all 
select b from #t where b > a 

-- option 3 - A udf
create function dbo.GREATEST
( 
    @a as sql_variant,
    @b as sql_variant
)
returns sql_variant
begin   
    declare @max sql_variant 
    if @a is null or @b is null return null
    if @b > @a return @b  
    return @a 
end


select dbo.GREATEST(a,b)
from #t

kristof

Diposting jawaban ini:

create table #t (id int IDENTITY(1,1), a int, b int)
insert #t
select 1,2 union all
select 3,4 union all
select 5,2

select id, max(val)
from #t
    unpivot (val for col in (a, b)) as unpvt
group by id
Sam Saffron
sumber
1
Catatan: implementasi fungsi TERBESAR akan cocok dengan perilaku oracle untuk 2 params, jika ada param yang null akan mengembalikan null
Sam Saffron
2
Anda harus berhati-hati saat menggunakan sql_variant. Fungsi Anda akan memberikan hasil yang tidak terduga dalam situasi berikut: SELECT dbo.greatest (CAST (0,5 AS FLOAT), 100)
Neil
@ Neil benar (saya belajar dengan cara yang sulit), bagaimana Anda meningkatkan fungsi ini untuk mencegah masalah seperti ini?
Luca
3

Berikut adalah contoh kasus yang harus menangani nulls dan akan bekerja dengan versi MSSQL yang lebih lama. Ini didasarkan pada fungsi sebaris di salah satu contoh populer:

case
  when a >= b then a
  else isnull(b,a)
end
scradam
sumber
2

Saya mungkin tidak akan melakukannya dengan cara ini, karena ini kurang efisien daripada konstruksi KASUS yang telah disebutkan - kecuali, mungkin, Anda memiliki mencakup indeks untuk kedua pertanyaan. Apa pun itu, ini adalah teknik yang berguna untuk masalah serupa:

SELECT OrderId, MAX(Price) as Price FROM (
   SELECT o.OrderId, o.NegotiatedPrice as Price FROM Order o
   UNION ALL
   SELECT o.OrderId, o.SuggestedPrice as Price FROM Order o
) as A
GROUP BY OrderId
Mark Brackett
sumber
2

Untuk jawaban di atas mengenai jumlah besar, Anda bisa melakukan perkalian sebelum penambahan / pengurangan. Ini agak bulkier tetapi tidak membutuhkan gips. (Saya tidak bisa berbicara untuk kecepatan tetapi saya menganggap itu masih cukup cepat)

SELECT 0,5 * ((@ val1 + @ val2) + ABS (@ val1 - @ val2))

Perubahan menjadi

SELECT @ val1 * 0.5 + @ val2 * 0.5 + ABS (@ val1 * 0.5 - @ val2 * 0.5)

setidaknya alternatif jika Anda ingin menghindari casting.

deepee1
sumber
2

Ini adalah versi IIF dengan penanganan NULL (berdasarkan jawaban Xin):

IIF(a IS NULL OR b IS NULL, ISNULL(a,b), IIF(a > b, a, b))

Logikanya adalah sebagai berikut, jika salah satu dari nilai adalah NULL, kembalikan yang bukan NULL (jika keduanya NULL, NULL dikembalikan). Kalau tidak, kembalikan yang lebih besar.

Hal yang sama dapat dilakukan untuk MIN.

IIF(a IS NULL OR b IS NULL, ISNULL(a,b), IIF(a < b, a, b))
jahu
sumber
1

Anda dapat melakukan sesuatu seperti ini:

select case when o.NegotiatedPrice > o.SuggestedPrice 
then o.NegotiatedPrice
else o.SuggestedPrice
end
Per Hornshøj-Schierbeck
sumber
1
SELECT o.OrderID
CASE WHEN o.NegotiatedPrice > o.SuggestedPrice THEN
 o.NegotiatedPrice
ELSE
 o.SuggestedPrice
END AS Price
Wayne
sumber
1
CREATE FUNCTION [dbo].[fnMax] (@p1 INT, @p2 INT)
RETURNS INT
AS BEGIN

    DECLARE @Result INT

    SET @p2 = COALESCE(@p2, @p1)

    SELECT
        @Result = (
                   SELECT
                    CASE WHEN @p1 > @p2 THEN @p1
                         ELSE @p2
                    END
                  )

    RETURN @Result

END
andrewc
sumber
1

Dalam bentuknya yang paling sederhana ...

CREATE FUNCTION fnGreatestInt (@Int1 int, @Int2 int )
RETURNS int
AS
BEGIN

    IF @Int1 >= ISNULL(@Int2,@Int1)
        RETURN @Int1
    ELSE
        RETURN @Int2

    RETURN NULL --Never Hit

END
jsmink
sumber
1

Untuk SQL Server 2012:

SELECT 
    o.OrderId, 
    IIF( o.NegotiatedPrice >= o.SuggestedPrice,
         o.NegotiatedPrice, 
         ISNULL(o.SuggestedPrice, o.NegiatedPrice) 
    )
FROM 
    Order o
Steve Ford
sumber
1

Inilah jawaban @Scott Langham dengan penanganan NULL yang sederhana:

SELECT
      o.OrderId,
      CASE WHEN (o.NegotiatedPrice > o.SuggestedPrice OR o.SuggestedPrice IS NULL) 
         THEN o.NegotiatedPrice 
         ELSE o.SuggestedPrice
      END As MaxPrice
FROM Order o
mohghaderi
sumber
0
select OrderId, (
    select max([Price]) from (
        select NegotiatedPrice [Price]
        union all
        select SuggestedPrice
    ) p
) from [Order]
kesalahan
sumber
0
 -- Simple way without "functions" or "IF" or "CASE"
 -- Query to select maximum value
 SELECT o.OrderId
  ,(SELECT MAX(v)
   FROM (VALUES (o.NegotiatedPrice), (o.SuggestedPrice)) AS value(v)) AS MaxValue
  FROM Order o;
ashraf mohammed
sumber
Meskipun penggunaan VALUESinline seperti itu menarik, saya tidak yakin ini lebih sederhana dari CASEatau IFF. Saya akan tertarik untuk melihat bagaimana kinerja solusi ini melawan opsi lain
Chris Schaller
0

Memperluas jawaban Xin dan menganggap tipe nilai perbandingannya adalah INT, pendekatan ini juga berfungsi:

SELECT IIF(ISNULL(@A, -2147483648) > ISNULL(@B, -2147483648), @A, @B)

Ini adalah tes lengkap dengan nilai contoh:

DECLARE @A AS INT
DECLARE @B AS INT

SELECT  @A = 2, @B = 1
SELECT  IIF(ISNULL(@A, -2147483648) > ISNULL(@B, -2147483648), @A, @B)
-- 2

SELECT  @A = 2, @B = 3
SELECT  IIF(ISNULL(@A, -2147483648) > ISNULL(@B, -2147483648), @A, @B)
-- 3

SELECT  @A = 2, @B = NULL
SELECT  IIF(ISNULL(@A, -2147483648) > ISNULL(@B, -2147483648), @A, @B)
-- 2    

SELECT  @A = NULL, @B = 1
SELECT  IIF(ISNULL(@A, -2147483648) > ISNULL(@B, -2147483648), @A, @B)
-- 1
Chris Porter
sumber
0

Di MemSQL lakukan hal berikut:

-- DROP FUNCTION IF EXISTS InlineMax;
DELIMITER //
CREATE FUNCTION InlineMax(val1 INT, val2 INT) RETURNS INT AS
DECLARE
  val3 INT = 0;
BEGIN
 IF val1 > val2 THEN
   RETURN val1;
 ELSE
   RETURN val2;
 END IF; 
END //
DELIMITER ;

SELECT InlineMax(1,2) as test;
Elang gurun
sumber
-1

Di Presto Anda bisa menggunakan digunakan

SELECT array_max(ARRAY[o.NegotiatedPrice, o.SuggestedPrice])
maxymoo
sumber