2012-03-27 2 views
4

다른 기준과 비교 한 기준을 충족하는 그룹에 대해서만 그룹화 된 결과 집합을 필터링 할 수있는 방법은 무엇입니까? 예를 들어 구성 레코드의 수가 최대 인 그룹 만? 빈 레코드의 마지막 HAVING 절 결과의 추가가 ... 무엇을SQL 그룹을 서로 비교하십시오.

SELECT * FROM (
    SELECT *, COUNT(*) AS Records 
    FROM  T 
    GROUP BY X 
) t HAVING Records = MAX(Records); 

일이야 그러나 :

나는대로 다음과 하위 쿼리가 트릭을해야한다고 생각했다?

+1

Juho의 대답은 당신이 필요로하는 무엇을 제공하지 않는 경우 , 어떤 데이터베이스 유형을 입력하십시오 (oracle, mysql, sql server 등) (SQL을 넣은 태그를 사용하여). 일반 SQL 솔루션 만 원하면 메시지 본문에 언급하십시오. 게시물 및 sqlfiddle.com에 샘플 데이터 및 테이블 구조를 추가하는 데 시간이 걸리면 사람들이보다 쉽게 ​​질문을 볼 수 있습니다. –

+1

@LevinMagruder : MySQL 5.1; 샘플 데이터 http://sqlfiddle.com/#!3/b4306/4 – eggyal

+0

괜찮아요, 전 mysql을 사용하지 않지만 누군가가 당신에게 내가 아래에 보여준 것보다 간단한 쿼리를 보여 주며 답을 답으로 표시 할 것입니다. 하지만 내 대답이 도움이되고 당신이 내게 upvote, 감사를 쏘고 싶다면. 이와 같이 많은 문제가있는 경우 "그룹당 최대 n 개"라는 질문을 읽으면 재미있는 방법이 많이 있습니다. –

답변

1

정확한 질문을 보려면, 더 많은 레코드가있는 다른 그룹이없는 레코드 그룹이 필요합니다. 당신이

SELECT taxid, COUNT(*) as howMany 
GROUP by taxid 

말한다면 당신은 모든 군과 카운트

그런 다음 당신이 하위 쿼리를함으로써 테이블로 표현하고, 그것에게 별칭을주는 것을 처리 할 수 ​​있습니다 얻을. 아래에서는 쿼리의 두 개의 "복사본"에 X와 Y라는 이름을 할당하고 하나의 테이블에 더 이상없는 택시를 요청합니다. 동일한 번호를 가진 두 개가 있다면 두 개 이상을 얻을 것입니다. 서로 다른 데이터베이스는 TOP 및 LIMIT와 같은 독점 구문을 사용하므로 이러한 종류의 쿼리를 더 간단하고 이해하기 쉽습니다. (난 당신이 내가 아는 모든 RDBMS에 실패 어떤 SELECT *, COUNT(*) FROM T GROUP BY X을 게시 한 이후 사용하는 가정)의 MySQL에서

SELECT taxid FROM 
(select taxid, count(*) as HowMany from flats 
GROUP by taxid) as X 

WHERE NOT EXISTS 
(
SELECT * from 
(
    SELECT taxid, count(*) as HowMany FROM 
    flats 
    GROUP by taxid 
    ) AS Y 
    WHERE Y.howmany > X.howmany 
) 
+0

나는'WHERE' 절에서 서브 쿼리를 반복함으로써 최대 행 수를 추출 할 수 있다는 것을 알고있다. (단지'max() '를 사용하여 잘 동작한다.) 그러나 동일한 서브 쿼리를 호출하는 것이 다소 낭비된다. 타임스; 'WHERE' 절의'FROM' 절에서 부질의 결과로 임시 테이블을 참조 할 수있는 방법이 있습니까? – eggyal

0

이 시도 :

SELECT * FROM (
    SELECT *, MAX(Records) as max_records FROM (
    SELECT *, COUNT(*) AS Records 
    FROM T 
    GROUP BY X 
) t 
) WHERE Records = max_records 

내가 지금이 쿼리의 유효성을 테스트 할 수 없음을 죄송합니다.

+0

두 번째 수준 쿼리의'SELECT MAX (Records)'는 레코드 집합을'Records'와'max_records' 필드가 반드시 같지 않은 레코드 하나만 잘라냅니다 (따라서 전체 결과는 오직 0으로만 구성됩니다) 또는 하나의 기록); 아마도 이것은 내 원래 쿼리에 의해 암시 된 것이므로 결과가 없습니다. – eggyal

4

. 다음을 사용할 수 있습니다 :

SELECT T.* 
FROM T 
     INNER JOIN 
     ( SELECT X, COUNT(*) AS Records 
      FROM T 
      GROUP BY X 
      ORDER BY Records DESC 
      LIMIT 1 
     ) T2 
      ON T2.X = T.X 

이 테스트는 MySQL에서 테스트되었으며 암시 적 그룹화/집계를 제거합니다.

당신이 윈도우 기능과 넥타이 또는 공통 테이블식이 TOP/LIMIT 중 하나를 사용할 수있는 경우는 심지어 짧아 질 :

윈도우 된 기능 + CTE : (MS SQL-서버 & PostgreSQL의 테스트를 거침)

WITH CTE AS 
( SELECT *, COUNT(*) OVER(PARTITION BY X) AS Records 
    FROM T 
) 
SELECT * 
FROM CTE 
WHERE Records = (SELECT MAX(Records) FROM CTE) 

TOP (테스트 MS-SQL 서버)와 윈도우 된 기능

SELECT TOP 1 WITH TIES * 
FROM ( SELECT *, COUNT(*) OVER(PARTITION BY X) [Records] 
      FROM T 
     ) 
ORDER BY Records DESC 

마지막으로 oracle에서 작동하는 솔루션을 추가하지 않으므로 apolgies를 사용하지 않았습니다 ...


편집

계정 관계를 고려하지 않은 MySQL을위한 내 솔루션, 그리고 발가락에 단계의이 종류에 대한 해결책에 대한 내 제안을 당신이 피하고 싶은 말한 (중복 하위 쿼리) 그래서 내가 그러나 단지의 경우가 여기 바람직하다 결국 도움이 될 수 있습니다 확실하지 않다 당신의 바이올린에 필요에 따라 작동하는 버전은 다음과 같습니다

SELECT T.* 
FROM T 
     INNER JOIN 
     ( SELECT X 
      FROM T 
      GROUP BY X 
      HAVING COUNT(*) = 
        ( SELECT COUNT(*) AS Records 
         FROM T 
         GROUP BY X 
         ORDER BY Records DESC 
         LIMIT 1 
        ) 
     ) T2 
      ON T2.X = T.X 
+0

첫번째 (mysql) 사람은 동점을 잃는다; 그것은 eggyal이 원했던 것일 수도 있습니다. 그렇지 않으면 카운트를 맞추기 위해 다시 작성해야한다고 생각합니다. 마지막 2 개는 동점을 잃지 않는다. –

+0

@LevinMagruder 예, 몇 분 전에이 사실을 알게되었습니다. 편집을 추가했지만, 이제 OP가 하위 쿼리를 반복 할 때 OP가 원하는 것으로 생각하지 않습니다.하지만 지금까지 해결할 수있는 한 피할 수없는 부분입니다. – GarethD

+0

내 "존재하지 않는"논리보다 직설적 인 +1. –

관련 문제