source

하위 쿼리 결과에서 MAX()를 사용하는 방법은 무엇입니까?

ittop 2023. 7. 6. 22:36
반응형

하위 쿼리 결과에서 MAX()를 사용하는 방법은 무엇입니까?

저는 오라클과 SQL 세계에 익숙하지 않습니다.저는 제가 평생 이해할 수 없는 질문에 약간의 문제가 있습니다. 저는 다른 접근법을 시도하는 데 몇 시간을 소비했고 제가 기대하는 결과를 얻을 수 없습니다.그래서 제 질문은 이렇습니다.

SELECT *
from(Select membership.mem_desc,membership.mem_max_rentals,membership_history.mem_type,      
    count(membership_history.MEM_TYPE) as membership_count
    from membership_history
    JOIN membership ON membership.mem_type = membership_history.mem_type
    group by (membership_history.mem_type,membership.mem_desc,membership.mem_max_rentals)
    ) g
WHERE g.membership_count = (select MAX(membership_count) from g); 

따라서 내부 쿼리는 완벽하게 작동하고 두 가지 결과를 반환합니다.이제 이 두 값을 얻었기 때문에, 저는 membership_count의 최대 값으로 행을 반환하는 방법을 찾고 있는데, 이 값이 계속 정체됩니다.위 쿼리에서 where 절에서 MAX()를 사용하려고 했지만 선택 항목 내부에서 'table not found'('g'를 의미함) 오류가 계속 발생합니다.그래서 제 질문은 제 하위 쿼리 결과에서 MAX() 함수를 어떻게 사용하나요?어떤 생각이나 제안을 해주시면 감사하겠습니다.!!

최대값을 찾는 하위 쿼리는 필요하지 않습니다.
대신, 행을 정렬한 후 번째 행만 필요합니다.

select * from (
  select 
    membership.mem_desc,
    membership.mem_max_rentals,
    membership_history.mem_type,      
    count(membership_history.MEM_TYPE) as membership_count
  from membership_history
  JOIN membership ON membership.mem_type = membership_history.mem_type
  group by (membership_history.mem_type,membership.mem_desc,membership.mem_max_rentals)
  ORDER BY 4 DESC  -- Added this line
) g
WHERE ROWNUM = 1. -- Added this line

이것은 모두 좋은 SQL입니다.

최대 기본 키 열 값을 사용하여 열 값을 찾는 가장 좋은 방법은 다음과 같습니다.

SELECT .... from tablename
WHERE ... AND
  (SELECT max(primary key name) FROM tablename WHERE .... ) = primary_key_name

이 예제는 스칼라 값을 반환합니다.

여기서 집계는 HAVING 절 또는 선택 목록에 포함된 하위 쿼리에 있지 않는 한 WHERE 절에 표시되지 않을 수 있으며, 집계되는 열은 SQL Server의 외부 참조입니다.

시연을 위해 'Info'라는 이름의 테이블에 레코드가 몇 개 있습니다.

--Select records from info
SELECT * FROM INFO

스크린샷

enter image description here

문제 설명:max id에 대한 INFO의 모든 세부 정보를 찾습니다.

SELECT * FROM INFO WHERE ID = MAX(ID)

그가 위의 스크립트를 실행했을 때 다음과 같은 오류가 발생했습니다.

147, 15,주 1, 시메지 147, 레벨 15, 상태 1, 라인 3
HAVING 절 또는 선택 목록에 포함된 하위 쿼리에 있지 않으면 WHERE 절에 집계가 표시되지 않을 수 있으며, 집계 중인 열은 외부 참조입니다.

솔루션이 쿼리 설명 자체에 제공되었음에도 불구하고 그는 이 문제를 해결할 수 없었습니다.

경험 부족으로 그는 오류 메시지를 기반으로 위 쿼리의 다른 버전을 생각해냈습니다.

SELECT * FROM INFO HAVING ID = MAX(ID)

16, 1, 1, 라인 1, 라인 1, 라인 8121, 레 16, 상 1, 선 1
.id 되어 있지 INFO.id ' 열은 집계 함수 또는 GROUP BY 절에 포함되어 있지 않으므로 HAVING 절에서 잘못되었습니다.

그가 실제로 원했던 것은 ID의 표 INFO max 값이었습니다.문제 진술을 바탕으로 올바른 솔루션은 다음과 같이 오류가 발생하지 않습니다.

SELECT * FROM INFO WHERE ID = (SELECT MAX(ID) FROM INFO)

스크린샷

enter image description here

액세스 쿼리 내에서 유사한 문제가 발생한 적이 있습니다... 이 스레드의 일부 주석을 바탕으로 볼 때, 액세스 MAX 기능은 기본 키 필드에서만 사용되어야 한다는 것을 이해해야 합니까? ...기본적으로, 엔티티와 관련된 주소를 정의하는 테이블이 있지만, 약간만 반전되어 있습니다. 1) 저장되면,레코드를 삭제하거나 변경할 수 없습니다(기업이 여러 개의 주소 레코드를 가질 수 있음). 2) 현재 엔티티 주소가 가질 수 있는 레코드: HOME(1개의 레코드) 또는 HOME 및 MAIL(2개의 레코드)...각 주소 레코드에는 HOME 레코드의 ID(ID)(HID는 기본 키가 아니며 고유하지 않음)와 일치하는 HOME ID(HID)와 엔티티 ID(EID)가 있습니다...하위 쿼리를 사용하여 특정 엔티티에 대한 최대(HID) 값을 가져오려고 하면 현재 주소만 반환됩니다. 하위 쿼리에서 MAX를 사용하여 찾은 것은 액세스가 하위 쿼리에 대해 일치하는 레코드가 너무 많다고 잘못 생각하여 실행되지 않거나...반환되지 않아야 할 행을 잘못 반환합니다.

이 문제를 해결할 수 있는 유일한 방법은 최대 하위 쿼리를 엔티티에 대한 최대 HID 값을 반환하는 최대 함수로 바꾸는 것이었습니다(이 함수는 VBA 내 DAO 로직과 함께 하위 쿼리 문을 사용함).

다음은 기본 쿼리의 일부인 HOME 하위 쿼리입니다(기본 쿼리는 엔티티당 하나의 행을 EID, 홈으로 반환해야 함).주소, 메일.주소)

Select *
From tbAddresses As tba1
Where tba1.aType = "Home"
  And tba1.HID = (Select MAX(tba2.HID) 
                      From tbAddresses As tba2 
                     Where tba1.EID = tba2.EID)

기본 쿼리는 홈 및 메일(표시되지 않음)의 위치 절이 아래 함수로 대체된 경우에만 제대로 작동합니다.MAX 서브쿼리가 위와 같이 포함되어 있으면 작동하지 않습니다.

따라서 MAX 함수가 작동하려면 기본 키 필드가 필요한 경우 쿼리가 실패하는 이유를 설명할 수 있지만, 이는 주요 제한 사항처럼 들릴 수 있습니다.

Where tba1.HID = fnGetMaxHID(tba1.EID) 

다음은 3개의 행만 반환해야 하는 일부 테스트 데이터입니다.

ID    HID    EID   aType  Address
 1      1    100   Home   Blah 1
 2      2    101   Home   Blah 2
 3      2    101   Mail   PO Box Blah 0
 4      4    102   Home   Blah 3
 5      5    101   Home   Blah 4

마지막으로 여러 버전의 Access Pro(2002, 2003, 2016)를 테스트한 결과 모두 동일한 결과를 얻었습니다.따라서 이 문제는 최대 함수의 고유한 결함이거나 무시되거나 무시된 버그의 일종입니까? ... 이 기능은 나에게는 해결책으로 작동하지만 다른 사람에게는 작동하지 않을 수 있으므로 MAX 기능이 명확하게 설명되면 좋을 것입니다.

당신은 다음과 같은 것을 시도할 수 있습니다.

 SELECT membership.mem_desc,membership.mem_max_rentals,membership_history.mem_type, membership_count, rank() over ORDER BY membership_count DESC as ranky
from
(Select membership.mem_desc,membership.mem_max_rentals,membership_history.mem_type,      
count(membership_history.MEM_TYPE) as membership_count
from membership_history
JOIN membership ON membership.mem_type = membership_history.mem_type
group by (membership_history.mem_type,membership.mem_desc,membership.mem_max_rentals)
) 
WHERE ranky =1;

된 표를 할 수 . 은 파생테절직수사없다니습용접을 제공합니다.table or view does not exist하여 최대 " " " " " " " " " 를 할 수 .HAVING 또는 조항또는Analytical Functions또는Rownum맘에 들다

select * from
      (Select membership.mem_desc,membership.mem_max_rentals,membership_history.mem_type,      
      count(membership_history.MEM_TYPE) as membership_count
      from membership_history a
      JOIN membership b ON b.mem_type = a.mem_type
      group by (membership_history.mem_type,membership.mem_desc,membership.mem_max_rentals)
      having count(a.MEM_TYPE) = (Select      
      MAX(count(a.MEM_TYPE)) from membership_history a
      JOIN membership b ON b.mem_type = a.mem_type
      group by (a.mem_type,b.mem_desc,b.mem_max_rentals)));

(또는)

select * from
(SELECT g.*,rank() over (order by membership_count desc) rnk from
      (Select membership.mem_desc,membership.mem_max_rentals,membership_history.mem_type,      
      count(membership_history.MEM_TYPE) as membership_count
      from membership_history
      JOIN membership ON membership.mem_type = membership_history.mem_type
      group by (membership_history.mem_type,membership.mem_desc,membership.mem_max_rentals)) g)
WHERE rnk=1;

(또는)

select * from
(SELECT g.*,rownum rn from
      (Select membership.mem_desc,membership.mem_max_rentals,membership_history.mem_type,      
      count(membership_history.MEM_TYPE) as membership_count
      from membership_history
      JOIN membership ON membership.mem_type = membership_history.mem_type
      group by (membership_history.mem_type,membership.mem_desc,membership.mem_max_rentals)
      order by membership_count desc) g)
WHERE rn=1;

ALL 비교 조건을 사용하는 것이 가장 깨끗한 해결책이라고 생각합니다.값을 목록 또는 하위 쿼리와 비교하는 데 사용됩니다.

SELECT 
  m.mem_desc,
  m.mem_max_rentals,
  mh.mem_type,      
  COUNT(mh.mem_type) as membership_count
FROM membership_history mh
JOIN membership m ON m.mem_type = mh.mem_type
GROUP BY mh.mem_type,m.mem_desc,m.mem_max_rentals
HAVING membership_count >= ALL (
  SELECT count(*)
  FROM membership_history
  GROUP BY mem_type
)   

언급URL : https://stackoverflow.com/questions/16182700/how-to-use-max-on-a-subquery-result

반응형