2009-12-30 4 views
1

최대 값과 최소값을 가져와야 할뿐만 아니라 같은 행에서 최대 또는 최소 값의 행 ID를 가져와야합니다.SQL 쿼리 최소값 최대 값

SELECT MIN([Value]), MAX([Value]), id 
FROM [AnalystEstimates].[dbo].[AnalystEstimateValues] 
GROUP BY indicatorid 
+0

ID와 MIN을 입력 한 다음 ID와 최대 값을 입력해야합니까? 2 행? 서로 옆에? –

+0

예 ID와 MIN, 그리고 ID와 Max가 서로 옆에 있으면 멋질 것입니다. – Woland

+2

@Woland : 변경된 요구 사항을 반영하여 질문을 편집 하시겠습니까? –

답변

3

질문에서 원하는 것이 무엇인지 분명하지 않습니다. 당신은 정말로 GROUP BY의 표시자를 원하니? 그렇지 않다면 아주 간단하고 이미 많은 해답을 가지고 있습니다. 그러나 GROUP BY를 원한다면 더 어려워지고 아무도 아직 확실히 얻지 못했습니다. 나는 또한 당신이 오직 하나의 행을 indicatorid 당 원한다고 가정하고, 최대/분이 같은 중복 행이 있다면, 둘 다 반환하는 대신 임의적으로 하나를 선택하는 것이 낫다. 여기

WITH 
    RowNumbers AS (
     SELECT ROW_NUMBER() OVER (ORDER BY indicatorid, value) AS RowNumber, * 
     FROM [AnalystEstimates].[dbo].[AnalystEstimateValues]), 
    MinRowNumbers AS (
     SELECT indicatorid, MIN(RowNumber) AS RowNumber FROM RowNumbers GROUP BY indicatorid), 
    MaxRowNumbers AS (
     SELECT indicatorid, MAX(RowNumber) AS RowNumber FROM RowNumbers GROUP BY indicatorid) 
SELECT 
    MinRowNumbers.indicatorid, 
    RN1.Value AS MinValue, 
    RN1.ID AS MinValueId, 
    RN2.Value AS MaxValue, 
    RN2.ID AS MaxValueId 
FROM MinRowNumbers 
JOIN MaxRowNumbers ON MinRowNumbers.indicatorid = MaxRowNumbers.indicatorid 
JOIN RowNumbers RN1 ON MinRowNumbers.RowNumber = RN1.RowNumber 
JOIN RowNumbers RN2 ON MaxRowNumbers.RowNumber = RN2.RowNumber 

내가 그것을 테스트하는 데 사용 일부 데이터입니다 :

CREATE TABLE AnalystEstimateValues (ID int, indicatorid int, Value int); 

INSERT INTO AnalystEstimateValues (ID, indicatorid , Value) VALUES 
(1, 1, 4), 
(2, 1, 4), 
(3, 2, 6), 
(4, 1, 2), 
(5, 2, 2), 
(6, 2, 5), 
(7, 3, 0); 

가 그리고 여기 얻을 출력의 여기

는 열팽창 계수를 사용하여 내 시도이다 (SQL Server 2005 또는 최신 필요) :

indicatorid MinValue MinValueId MaxValue MaxValueId 
      1  2   4  4   2 
      2  2   5  6   3 
      3  0   7  0   7 

원하는 내용이 아닌 경우 질문을 개선하여 원하는 것을 알려주십시오.


업데이트 : 여기 크레이그 영의 답변에 따라 대안 솔루션입니다하지만 사용하는 대신 부속 선택의 조인

WITH 
    UniqueIds AS (
     SELECT IndicatorId, Value, MIN(id) AS Id 
     FROM AnalystEstimateValues 
     GROUP BY IndicatorId, Value) 
SELECT 
    lims.IndicatorId, 
    MinValue, 
    T1.Id AS MinValueId, 
    MaxValue, 
    T2.Id AS MaxValueId 
FROM (
     SELECT 
      IndicatorId, 
      MIN(Value) as MinValue, 
      MAX(Value) as MaxValue 
     FROM AnalystEstimateValues 
     GROUP BY IndicatorId) lims 
JOIN UniqueIds T1 ON lims.IndicatorId = T1.IndicatorId AND lims.MinValue = T1.Value 
JOIN UniqueIds T2 ON lims.IndicatorId = T2.IndicatorId AND lims.MaxValue = T2.Value 

이 깨끗하고 아마도 더 빨리 내 첫 번째 버전보다, 내가 실행하지 않은 있지만, 이를 검증하기위한 성능 테스트.

+0

고마워요 그게 – Woland

+0

좋아, 운이 좋았어. :) 다음에 생각해 보면 응답 시간이 더 길어서 원하는 시간에 더 많은 시간을 보내야한다고 생각합니다. 사실이게이 문제를 해결하는 가장 좋은 방법이라고 생각하지 않습니다. 너무 느릴 수 있습니다. 귀하가 이미 동의 한 것을 보았습니다 만, 그렇게하기 전에 귀하의 데이터가 충분히 빠르다는 것을 확인 하셨기를 바랍니다. 누군가가 나중에 더 나은 방법으로 이것을 해결할 수 있기 때문에 원하는 것을 볼 수 있다면이 대답 대신 대답을 받아 들여야합니다. –

+0

저는 사용했던 구문에 익숙하지 않습니다. 나는 그것에 대해 읽어야한다. 실적 참고 사항으로, 2 개의 GROUP BY 하위 쿼리가 있습니다. 하나는 MIN에 대한 것이고 다른 하나는 MAX에 대한 것입니다. 이들을 단일 하위 쿼리로 결합하여 중요한 성능 향상을 도출 할 수 있어야합니다. –

0

ID로 그룹화 할 때 각 ID에 대한 최대/최소값이 반환됩니다. 최소 = 최대, 당신은

그렇지 않은 경우에는 같은 ID가 (이 묶여있을 수 최소 및 최대 값)을 얻을 것이다 경우이

SELECT tblFoo.ID, tblFoo.Value 
FROM tblFoo 
WHERE (((tblFoo.Value)=(SELECT MAX([tblFoo]![Value]) FROM tblFoo))) 
    OR (((tblFoo.Value)=(SELECT MIN([tblFoo]![Value]) FROM tblFoo))); 
+1

당신도 그룹화 구성을 잃어 버렸습니다. –

0
SELECT TOP 1 
    ID, 
    'min' as type, 
    value 
FROM 
    AnalystEstimateValues 
WHERE 
    value = (select min(value) from AnalystEstimateValues) 
UNION 
    SELECT TOP 1 
    ID, 
    'max' as type, 
    value 
FROM 
    AnalystEstimateValues 
WHERE 
    value = (select max(value) from AnalystEstimateValues) 
+1

그룹화 구성이 손실되었습니다. –

1

같은 것을 시도 /이 (ID있다가들) / 분당 최대 값.

기본적으로 2 행 또는 4 열을 가질 수 있습니다.

SELECT 
    Mn.ID, foo.MinVal, 
    Mx.ID, foo.MaxVal  
FROM 
    (
    SELECT 
     MIN([Value]) AS MinVal, 
     MAX([Value]) AS MaxVal, 
     indicatorid 
    FROM 
     [AnalystEstimates].[dbo].[AnalystEstimateValues] 
    GROUP BY 
     indicatorid 
    ) foo 
    JOIN 
    [AnalystEstimates].[dbo].[AnalystEstimateValues] Mn ON 
      foo.MinVal = Mn.[Value] AND foo.indicatorid = Mn.indicatorid 
    JOIN 
    [AnalystEstimates].[dbo].[AnalystEstimateValues] Mx ON 
      foo.MaxVal = Mx.[Value] AND foo.indicatorid = Mx.indicatorid 

편집 : MSSQL이없는하지만 당신이 MIN을 연결 한 행을 제공하지 않습니다

상단 솔루션/MAX가되지 않는 한,이 그것을 할 수 TIES

+0

ON foo.MinVal = Mn. [값] 및 ON foo.MaxVal = Mx. [값] – Woland

+0

중복이있을 수 있기 때문에값을 원하기 때문에 을 사용할 수 없습니까? ID 하나를 다른 ID보다 어떻게 결정합니까? – gbn

+0

이렇게 여러 결과를 반환하도록 허용하려면 표시 항목을 조인에 포함해야합니다. 그렇지 않으면 잘못된 그룹에서 행을 가져올 수 있습니다. 나는. 'ON foo.MinVal = Mn. [Value] AND foo.indicatorid = Mn.indicatorid'가 필요합니다. –

0

함께 정의 된 값 그래서 나는 그것을 시험 할 수 없다. 특히 대괄호는 조정이 필요할 수 있습니다. 그것보다 상당히 표준 SQL이어야하고 당신이 원하는 것을 수행해야합니다.

indicatorid로 그룹화 된 모든 min (id/value) 및 max (id/value)를 가져옵니다. 같은 행에 있습니다.

SELECT mint.indicatorid, mint.min_id, mint.min_value, maxt.max_id, maxt.max_value 
FROM (
    SELECT indicatorid, id as min_id, MIN([Value]) AS min_value 
    FROM [AnalystEstimates].[dbo].[AnalystEstimateValues] 
    HAVING [Value] = min_value 
    GROUP BY indicatorid 
) mint JOIN (
    SELECT indicatorid, id as max_id, MAX([Value]) AS max_value 
    FROM [AnalystEstimates].[dbo].[AnalystEstimateValues] 
    HAVING [Value] = max_value 
    GROUP BY indicatorid 
) maxt ON mint.indicatorid = maxt.indicatorid 
+1

집계 함수 나 GROUP BY 절에 포함되어 있지 않기 때문에 "ID '가 선택 목록에 유효하지 않습니다."라는 오류가 발생했습니다. – Woland

1

중요한 질문 마크 바이어스 '샘플 데이터는 고민 할 필요가 시나리오를 보여줍니다
:

  • IndicatorId = 1이 아이디의를 4.
  • 의 최대 값이 있습니다 것을 공유를 동일한 최대 값 (1 & 2).

두 ID 중 어느 것을 표시해야합니까?

가장 낮은 ID를 표시하는 것으로 충분하다고 가정했습니다. 다음 쿼리가 가장 효율적이어야하며 (indicatorid, Value)의 인덱스를 사용하면 도움이됩니다.

SELECT lims.*, 
     (
     SELECT MIN(id) 
     FROM AnalystEstimateValues m 
     WHERE m.IndicatorId = lims.IndicatorId 
      AND m.Value = lims.MinValue 
     ) AS MinId, 
     (
     SELECT MIN(id) 
     FROM AnalystEstimateValues m 
     WHERE m.IndicatorId = lims.IndicatorId 
      AND m.Value = lims.MaxValue 
     ) AS MaxId 
FROM (
     SELECT IndicatorId, 
       MIN(Value) as MinValue, 
       MAX(Value) as MaxValue 
     FROM AnalystEstimateValues 
     GROUP BY IndicatorId 
     ) lims 
+0

이는 예제 테스트 데이터에 따라 정확한 결과를 산출합니다. 그것은 상관 관계가있는 subselect를 사용하므로 항상 빠를 것이라고 확신하지 못합니다. 매우 작은 indicatorid 그룹이 너무 많으면 느려질 것입니다. 그러나 더 현실적인 데이터를 사용하지 않고 이러한 것들을 추측하는 것은 매우 어렵습니다. 나는 여전히 더 나은 방법이 있어야한다고 생각하지만 어쨌든 +1합니다. –

+0

나는 해결책의 수정 된 버전을 만들고 첫 번째 대답이 끝날 때까지 덧붙였다. 기본적으로 같은 일을하지만 상관 관계가있는 subselect 대신 JOIN을 사용합니다. I * guess * 이것은 더 빠를 것입니다. 그러나 확실히 알아 내기 위해서는 적절한 테스트가 필요합니다. 현실적인 테스트 데이터를 작성하기에는 너무 많은 노력을 기울일 예정이지만, 다른 누군가가이 작업을 수행한다면 (Woland?) 결과를 알고 싶습니다. –

+0

추 신 : 나는 아마도 많은 indicatorids가 없기 때문에 당신의 솔루션은 괜찮다고 생각합니다. –