ฉันมีสองตัวแปรหนึ่งที่เรียกว่าPaidThisMonth
และอื่น ๆ OwedPast
เรียกว่า ทั้งคู่เป็นผลลัพธ์ของแบบสอบถามย่อยบางรายการใน SQL ฉันจะเลือกขนาดเล็กกว่าสองค่าและคืนค่าเป็นชื่อได้PaidForPast
อย่างไร
MIN
ฟังก์ชั่นการทำงานในคอลัมน์ไม่ตัวแปร
ฉันมีสองตัวแปรหนึ่งที่เรียกว่าPaidThisMonth
และอื่น ๆ OwedPast
เรียกว่า ทั้งคู่เป็นผลลัพธ์ของแบบสอบถามย่อยบางรายการใน SQL ฉันจะเลือกขนาดเล็กกว่าสองค่าและคืนค่าเป็นชื่อได้PaidForPast
อย่างไร
MIN
ฟังก์ชั่นการทำงานในคอลัมน์ไม่ตัวแปร
คำตอบ:
ใช้กรณี:
Select Case When @PaidThisMonth < @OwedPast
Then @PaidThisMonth Else @OwedPast End PaidForPast
ในฐานะที่เป็นตาราง Inline มูลค่า UDF
CREATE FUNCTION Minimum
(@Param1 Integer, @Param2 Integer)
Returns Table As
Return(Select Case When @Param1 < @Param2
Then @Param1 Else @Param2 End MinValue)
การใช้งาน:
Select MinValue as PaidforPast
From dbo.Minimum(@PaidThisMonth, @OwedPast)
เพิ่ม: สิ่งนี้น่าจะดีที่สุดเมื่อพูดถึงค่าที่เป็นไปได้เพียงสองค่าหากมีมากกว่าสองค่าให้พิจารณาคำตอบของ Craigโดยใช้ส่วนคำสั่ง Values
SQL Server 2012 และ 2014 รองรับฟังก์ชั่น IIF (ต่อ, จริง, เท็จ) ดังนั้นสำหรับการเลือกน้อยที่สุดคุณสามารถใช้งานได้เช่น
SELECT IIF(first>second, second, first) the_minimal FROM table
ในขณะที่IIFเป็นเพียงชวเลขสำหรับการเขียนCASE...WHEN...ELSE
มันง่ายกว่าในการเขียน
โซลูชันที่ใช้ CASE, IIF และ UDF นั้นเพียงพอ แต่ไม่สามารถทำได้เมื่อขยายปัญหาไปยังเคสทั่วไปโดยใช้มากกว่า 2 ค่าเปรียบเทียบ โซลูชันทั่วไปใน SQL Server 2008+ ใช้แอปพลิเคชันที่แปลกประหลาดของ VALUES clause:
SELECT
PaidForPast=(SELECT MIN(x) FROM (VALUES (PaidThisMonth),(OwedPast)) AS value(x))
เครดิตเนื่องจากเว็บไซต์นี้: http://sqlblog.com/blogs/jamie_thomson/archive/2012/01/20/use-values-clause-to-get-the-maximum-value-from-some-columns-sql- เซิร์ฟเวอร์เสื้อ sql.aspx
MIN(x*(case x when 0 then null else 1 end))
ฉันเพิ่งมีสถานการณ์ที่ฉันต้องค้นหาจำนวนสูงสุด 4 ตัวเลือกในการอัปเดต ด้วยวิธีนี้คุณสามารถมีได้มากเท่าที่คุณต้องการ!
นอกจากนี้คุณยังสามารถแทนที่ตัวเลขด้วยการเลือกเพิ่มเติม
select max(x)
from (
select 1 as 'x' union
select 4 as 'x' union
select 3 as 'x' union
select 2 as 'x'
) a
การใช้งานที่ซับซ้อนมากขึ้น
@answer = select Max(x)
from (
select @NumberA as 'x' union
select @NumberB as 'x' union
select @NumberC as 'x' union
select (
Select Max(score) from TopScores
) as 'x'
) a
ฉันแน่ใจว่า UDF มีประสิทธิภาพที่ดีขึ้น
สำหรับ MySQL หรือ PostgreSQL 9.3+ วิธีที่ดีกว่าคือการใช้LEAST
และGREATEST
ฟังก์ชั่น
SELECT GREATEST(A.date0, B.date0) AS date0,
LEAST(A.date1, B.date1, B.date2) AS date1
FROM A, B
WHERE B.x = A.x
ด้วย:
GREATEST(value [, ...])
: ส่งคืนอาร์กิวเมนต์ที่ใหญ่ที่สุด (มูลค่าสูงสุด) จากค่าที่มีให้LEAST(value [, ...])
ส่งคืนอาร์กิวเมนต์ที่เล็กที่สุด (ค่าต่ำสุด) จากค่าที่มีให้ลิงค์เอกสาร:
นี่คือเคล็ดลับหากคุณต้องการคำนวณค่าสูงสุด (ฟิลด์, 0):
SELECT (ABS(field) + field)/2 FROM Table
กลับ 0 ถ้าเป็นลบอื่นกลับมาfield
field
SELECT @a - ( ABS(@a-@b) + (@a-@b) ) / 2
ใช้คำสั่ง CASE
ตัวอย่าง B ในหน้านี้ควรอยู่ใกล้กับสิ่งที่คุณพยายามทำ:
http://msdn.microsoft.com/en-us/library/ms181765.aspx
นี่คือรหัสจากหน้า:
USE AdventureWorks; GO SELECT ProductNumber, Name, 'Price Range' = CASE WHEN ListPrice = 0 THEN 'Mfg item - not for resale' WHEN ListPrice < 50 THEN 'Under $50' WHEN ListPrice >= 50 and ListPrice < 250 THEN 'Under $250' WHEN ListPrice >= 250 and ListPrice < 1000 THEN 'Under $1000' ELSE 'Over $1000' END FROM Production.Product ORDER BY ProductNumber ; GO
ใช้ตาราง temp เพื่อแทรกช่วงของค่าจากนั้นเลือก min / max ของตาราง temp จากภายในกระบวนงานที่เก็บไว้หรือ UDF นี่คือโครงสร้างพื้นฐานดังนั้นโปรดแก้ไขได้ตามต้องการ
ตัวอย่างเช่น:
CREATE PROCEDURE GetMinSpeed() AS
BEGIN
CREATE TABLE #speed (Driver NVARCHAR(10), SPEED INT);
'
' Insert any number of data you need to sort and pull from
'
INSERT INTO #speed (N'Petty', 165)
INSERT INTO #speed (N'Earnhardt', 172)
INSERT INTO #speed (N'Patrick', 174)
SELECT MIN(SPEED) FROM #speed
DROP TABLE #speed
END
สามารถใช้งานได้ถึง 5 วันและจัดการกับค่า Null ไม่สามารถทำให้มันเป็นฟังก์ชัน Inline ได้
CREATE FUNCTION dbo.MinDate(@Date1 datetime = Null,
@Date2 datetime = Null,
@Date3 datetime = Null,
@Date4 datetime = Null,
@Date5 datetime = Null)
RETURNS Datetime AS
BEGIN
--USAGE select dbo.MinDate('20120405',null,null,'20110305',null)
DECLARE @Output datetime;
WITH Datelist_CTE(DT)
AS (
SELECT @Date1 AS DT WHERE @Date1 is not NULL UNION
SELECT @Date2 AS DT WHERE @Date2 is not NULL UNION
SELECT @Date3 AS DT WHERE @Date3 is not NULL UNION
SELECT @Date4 AS DT WHERE @Date4 is not NULL UNION
SELECT @Date5 AS DT WHERE @Date5 is not NULL
)
Select @Output=Min(DT) FROM Datelist_CTE
RETURN @Output
END
สร้างด้วยตรรกะ / รหัสที่ยอดเยี่ยมจาก mathematix และ scottyc ฉันส่ง:
DECLARE @a INT, @b INT, @c INT = 0
WHILE @c < 100
BEGIN
SET @c += 1
SET @a = ROUND(RAND()*100,0)-50
SET @b = ROUND(RAND()*100,0)-50
SELECT @a AS a, @b AS b,
@a - ( ABS(@a-@b) + (@a-@b) ) / 2 AS MINab,
@a + ( ABS(@b-@a) + (@b-@a) ) / 2 AS MAXab,
CASE WHEN (@a <= @b AND @a = @a - ( ABS(@a-@b) + (@a-@b) ) / 2)
OR (@a >= @b AND @a = @a + ( ABS(@b-@a) + (@b-@a) ) / 2)
THEN 'Success' ELSE 'Failure' END AS Status
END
แม้ว่าการกระโดดจากฟังก์ชั่น MIN ของสก็อตตี้ไปยังฟังก์ชั่น MAX ควรจะชัดเจนสำหรับฉัน แต่มันก็ไม่ได้ดังนั้นฉันจึงแก้ไขและรวมไว้ที่นี่: SELECT @ a + (ABS (@ b- @ a) + ( @ b- @ a)) / 2 ตัวเลขที่สร้างแบบสุ่มในขณะที่ไม่ใช่ข้อพิสูจน์อย่างน้อยควรโน้มน้าวให้ผู้สงสัยว่าสูตรทั้งสองนั้นถูกต้อง