여러 열의 SQL MAX?
여러 열의 최대값 중 행당 하나의 값을 반환하려면 어떻게 해야 합니까?
테이블명
[Number, Date1, Date2, Date3, Cost]
다음과 같은 것을 반품해야 합니다.
[Number, Most_Recent_Date, Cost]
질문?
또 좋은 .Max
및 을 사용한
SELECT [Other Fields],
(SELECT Max(v)
FROM (VALUES (date1), (date2), (date3),...) AS value(v)) as [MaxDate]
FROM [YourTableName]
"테이블로 구성할 행 값 식 집합을 지정합니다.Transact-SQL 테이블 값 생성자를 사용하면 단일 DML 문에서 여러 행의 데이터를 지정할 수 있습니다.테이블 값 생성자는 INSERT...의 VALUES 절로 지정할 수 있습니다.VALUES 스테이트먼트 또는 MERGE 스테이트먼트의 USING 절 또는 FROM 절 중 하나의 파생 테이블로 사용할 수 있습니다."
MySQL 또는 Postgre를 사용하는 경우SQL, Oracle 또는 BigQuery를 사용할 수 있습니다.
SELECT GREATEST(col1, col2 ...) FROM table
이것은 오래된 대답이고 여러모로 깨졌다.
https://stackoverflow.com/a/6871572/194653 를 참조해 주세요.https://stackoverflow.com/a/6871572/194653 는, 보다 많은 업베이트가 있어 sql server 2008+ 와 연동해, 늘(null)
독창적이지만 문제가 있는 답변:
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
세 이 더 요.UNPIVOT
1)이, 으로 (1 (2)보다훨씬 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 (루 ( 1 )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(행당 하위 쿼리)
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 ()3 (시뮬레이션)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
스칼라 함수는 모든 종류의 성능 문제를 일으키므로 가능하면 인라인 테이블 값 함수로 논리를 정리하는 것이 좋습니다.이 함수는 최대 10개의 날짜 목록에서 최소/최대 날짜를 선택한 일부 사용자 정의 함수를 대체하는 데 사용되었습니다.100만 행의 데이터 세트로 테스트한 결과, 스칼라 함수는 쿼리를 종료하기 전에 15분 이상 걸렸습니다.인라인 TVF는 결과 세트를 임시 테이블로 선택하는 것과 같은 1분이 걸렸습니다.이 기능을 사용하려면 SELECT 또는 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)
)
다음의 2개의 샘플 중 하나가 동작합니다.
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
두 번째는 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
T-SQL(MSSQL 2008+)의 경우
SELECT
(SELECT
MAX(MyMaxName)
FROM ( VALUES
(MAX(Field1)),
(MAX(Field2))
) MyAlias(MyMaxName)
)
FROM MyTable1
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
SELECT
CASE
WHEN Date1 >= Date2 AND Date1 >= Date3 THEN Date1
WHEN Date2 >= Date3 THEN Date2
ELSE Date3
END AS MostRecentDate
이것은, 케이스 스테이트먼트가 순서대로 평가되기 때문에, 기입이 조금 쉬워지고 평가 스텝은 생략됩니다.
불행하게도 라세의 대답은 겉으로 보기에는 분명하지만 결정적인 결함이 있다.NULL 값은 처리할 수 없습니다.단일 NULL 값을 지정하면 Date1이 반환됩니다.안타깝게도 이 문제를 해결하려는 시도는 매우 혼란스러워지기 쉽고 4개 이상의 값으로 확장되지 않습니다.
databys의 첫 번째 답변은 좋아보였습니다.그러나 하나의 테이블에서 단순한 3개의 값이 아닌 다중 테이블 결합에서 3개의 값으로 쉽게 추정할 수 있을지는 명확하지 않습니다.나는 단지 3컬럼의 최대치를 얻기 위해 이러한 쿼리를 서브쿼리로 바꾸는 것을 피하고 싶었고, 또한 데이터 시스템의 훌륭한 아이디어가 약간 정리될 것이라고 확신했다.
자, 이제 더 이상 말하지 말고, (데이터베이스의 아이디어에서 파생된) 솔루션을 제시하겠습니다.
교차 결합 선택 상수를 사용하여 다중 테이블 결합의 효과를 시뮬레이션합니다.주의할 점은 필요한 에일리어스가 모두 올바르게 전달된다는 것입니다(항상 그렇지는 않습니다).이것에 의해, 패턴을 심플하게 해, 추가 열을 통해서 꽤 측정할 수 있게 됩니다.
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
문제: 엔티티에 지정된 최소 환율 값을 선택합니다.요건:대리점 요율은 null일 수 있습니다.
[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를 사용하는 경우 UNPIVOT 기능을 사용할 수 있습니다.다음으로 완전한 예를 제시하겠습니다.
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
CROSS APPLY 사용(2005+용)...
SELECT MostRecentDate
FROM SourceTable
CROSS APPLY (SELECT MAX(d) MostRecentDate FROM (VALUES (Date1), (Date2), (Date3)) AS a(d)) md
SQL Server 2012부터는 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
마지막으로 다음과 같은 경우:
- SQL Server 2022 (16.x) 미리보기
- Azure SQL 데이터베이스
- Azure SQL 관리 인스턴스
GREATE도 사용할 수 있습니다.다른 T-SQL 함수와 마찬가지로 몇 가지 중요한 주의사항을 다음에 제시하겠습니다.
- 모든 인수가 동일한 데이터 유형을 가지며 그 유형이 비교용으로 지원되는 경우 GREAST는 해당 유형을 반환합니다.
- 그렇지 않으면 함수는 모든 인수를 비교 전에 가장 우선순위가 높은 데이터 유형으로 암묵적으로 변환하고 이 유형을 반환 유형으로 사용합니다.
- 하나 이상의 인수가 NULL이 아닌 경우 비교 시 NULL 인수는 무시됩니다.모든 인수가 NULL인 경우 GREATE는 NULL을 반환합니다.
8,000바이트를 초과하는 varchar(max), varbinary(max) 또는 nvarchar(max), 커서, 지오메트리, 지리, 이미지, 바이트가 아닌 사용자 정의 유형, ntext, table, text 및 xml의 비교에는 지원되지 않습니다.
사용해보시기 바랍니다.UNPIVOT
:
SELECT MAX(MaxDt) MaxDt
FROM tbl
UNPIVOT
(MaxDt FOR E IN
(Date1, Date2, Date3)
)AS unpvt;
저는 케이스에 근거한 솔루션을 선호합니다.예를 들어 크로스 어플리케이션, 값(), 커스텀 기능 등 가능한 다른 솔루션과 비교하여 퍼포먼스 저하에 대한 영향이 가장 적다고 가정합니다.
가능한 테스트 케이스의 대부분을 null 값을 처리하는 버전을 다음에 나타냅니다.
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
;
결과는 다음과 같습니다.
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
http://www.experts-exchange.com/Microsoft/Development/MS-SQL-Server/Q_24204894.html의 ScottPletcher 솔루션을 기반으로 UNION ALL을 사용하여 최대 13개의 날짜 값을 찾는 함수 세트(GetMaxOfDates3, GetMaxOfDates13 등)를 만들었습니다.동일한 행에서 최대값 가져오기 T-SQL 함수를 참조하십시오. 그러나 이러한 함수를 작성할 때 UNPIVOT 솔루션을 고려하지 않았습니다.
CREATE FUNCTION GetMaxOfDates13 (
@value01 DateTime = NULL,
@value02 DateTime = NULL,
@value03 DateTime = NULL,
@value04 DateTime = NULL,
@value05 DateTime = NULL,
@value06 DateTime = NULL,
@value07 DateTime = NULL,
@value08 DateTime = NULL,
@value09 DateTime = NULL,
@value10 DateTime = NULL,
@value11 DateTime = NULL,
@value12 DateTime = NULL,
@value13 DateTime = NULL
)
RETURNS DateTime
AS
BEGIN
RETURN (
SELECT TOP 1 value
FROM (
SELECT @value01 AS value UNION ALL
SELECT @value02 UNION ALL
SELECT @value03 UNION ALL
SELECT @value04 UNION ALL
SELECT @value05 UNION ALL
SELECT @value06 UNION ALL
SELECT @value07 UNION ALL
SELECT @value08 UNION ALL
SELECT @value09 UNION ALL
SELECT @value10 UNION ALL
SELECT @value11 UNION ALL
SELECT @value12 UNION ALL
SELECT @value13
) AS [values]
ORDER BY value DESC
)
END –FUNCTION
GO
CREATE FUNCTION GetMaxOfDates3 (
@value01 DateTime = NULL,
@value02 DateTime = NULL,
@value03 DateTime = NULL
)
RETURNS DateTime
AS
BEGIN
RETURN dbo.GetMaxOfDates13(@value01,@value02,@value03,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL)
END –FUNCTION
날짜를 전달한 후 아래와 같이 선택문에 함수를 추가할 수 있습니다.숫자, dbo.fxMost_Recent_Date(날짜 1, 날짜 2, 날짜 3), 비용 선택
create FUNCTION fxMost_Recent_Date
(@Date1 smaldatime, @Date2 smaldatime, @Date3 smaldatime ) smaldatime AS BEGIN DECLARE @Result smaldatime을 반환합니다.
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
끝.
CASE를 사용하는 다른 방법:
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
이 솔루션에서는 null 값 비교도 처리할 수 있습니다.하나의 쿼리로 작성하면 간단하게 할 수 있지만, 설명을 위해 CTE를 사용하고 있습니다.스텝 1에서는 비교를 3에서2로, 스텝 2에서는 2에서1로 줄이는 것입니다.
with x1 as
(
select 1 as N1, null as N2, 3 as N3
union
select 1 as N1, null as N2, null as N3
union
select null as N1, null as N2, null as N3
)
,x2 as
(
select
N1,N2,N3,
IIF(Isnull(N1,0)>=Isnull(N2,0),N1,N2) as max1,
IIF(Isnull(N2,0)>=Isnull(N3,0),N2,N3) as max2
from x1
)
,x3 as
(
select N1,N2,N3,max1,max2,
IIF(IsNull(max1,0)>=IsNull(max2,0),max1,max2) as MaxNo
from x2
)
select * from x3
출력:
여기 좋은 해결책이 있습니다.
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 등에 있는지...M$ACCESS 도움말에는 다음과 같은 함수가 있습니다.MAXA(Value1;Value2;...)
그렇게 하기로 되어 있어요.
희망은 누군가를 도울 수 있다.
P.D.: 값은 열 또는 계산된 값 등이 될 수 있습니다.
위 표는 급여1, 급여2, 급여3, 급여4를 열로 한 직원 급여표입니다.아래 쿼리는 4개의 열 중 최대값을 반환합니다.
select
(select Max(salval) from( values (max(salary1)),(max(salary2)),(max(salary3)),(max(Salary4)))alias(salval)) as largest_val
from EmployeeSalary
위의 쿼리를 실행하면 출력이 bigest_val(10001)로 표시됩니다.
위 쿼리의 논리는 다음과 같습니다.
select Max(salvalue) from(values (10001),(5098),(6070),(7500))alias(salvalue)
출력은 10001이 됩니다.
언급URL : https://stackoverflow.com/questions/71022/sql-max-of-multiple-columns
'programing' 카테고리의 다른 글
[ SQL Server Table ]컬럼의 문자열을 치환하는 방법 (0) | 2023.04.07 |
---|---|
SQL Server Management Studio에서 기억된 로그인 및 암호 목록 제거 (0) | 2023.04.07 |
VB의 C# 버전은 무엇입니까?NET의 Input Box? (0) | 2023.04.07 |
varchar와 nvarchar의 차이점은 무엇입니까? (0) | 2023.04.07 |
TSQL에서 PRINT 버퍼를 플러시하는 방법 (0) | 2023.04.07 |