복붙노트

[SQL] 에 의해 그룹을 사용하고 절을 가진

SQL

에 의해 그룹을 사용하고 절을 가진

다음 스키마를 사용하여 :

Supplier (sid, name, status, city)
Part (pid, name, color, weight, city)
Project (jid, name, city)
Supplies (sid, pid, jid**, quantity)

이 내 대답했다 :

1.

SELECT s.sid, s.name
FROM Supplier s, Supplies su, Project pr
WHERE s.sid = su.sid AND su.jid = pr.jid
GROUP BY s.sid, s.name
HAVING COUNT (DISTINCT pr.jid) >= 2 

2.

SELECT s.sid, s.name
FROM Suppliers s, Supplies su, Project pr, Part p
WHERE s.sid = su.sid AND su.pid = p.pid AND su.jid = pr.jid
GROUP BY s.sid, s.name
HAVING COUNT (DISTINCT pr.jid)>=2

내가 제대로 쓴 경우 사람의 확인은 할 수 있습니까? 나는 조금을 혼동하고있어 어떻게 그룹으로와 HAVING 절 작업

해결법

  1. ==============================

    1.데의 의미

    데의 의미

    더 나은 가진 이해하려면 이론적 인 관점에서 볼 필요가있다.

    에 의해 그룹은 테이블을 소요하고 다른 테이블로를 요약하는 쿼리입니다. 당신은 (당신이 그룹에 의해 지정하는 속성에 근거) 부분 집합으로 원래의 테이블을 그룹화하여 원래의 테이블을 요약한다. 이 그룹의 각각은 하나 개의 튜플을 얻을 것입니다.

    갖는이 실행 된하여 쿼리의 선택 부분을 계산하기 전에 그룹 후 WHERE 절에 단순히 동일합니다.

    쿼리는 말할 수 있습니다 :

    select a, b, count(*) 
    from Table 
    where c > 100 
    group by a, b 
    having count(*) > 10;
    

    이 쿼리의 평가는 다음과 같은 단계로 볼 수있다 :

    당신은 표 테이블을 반환 복잡한 쿼리 (크로스 제품, 조인, 노동 조합 등)이 될 수 있습니다 복잡한 쿼리에이를 확장 할 수 있습니다.

    사실,있는 것은 문법 설탕과 SQL의 성능을 확장하지 않습니다. 주어진 쿼리 :

    SELECT list 
    FROM table
    GROUP BY attrList
    HAVING condition;
    

    로 다시 작성할 수 있습니다 :

    SELECT list from (
       SELECT listatt 
       FROM table 
       GROUP BY attrList) as Name
    WHERE condition;
    

    listatt는 속성는 GROUP BY 및 목록 및 조건에 사용 된 표현을 포함하는 목록입니다. (AS)와 함께이 목록에 어떤 식의 이름을 지정해야 할 수도 있습니다. 예를 들어, 위의 예제 쿼리는 다음과 같이 쓸 수있다 :

    select a, b, count 
    from (select a, b, count(*) as count
          from Table 
          where c > 100
          group by a, b) as someName
    where count > 10;
    

    당신이 필요로하는 솔루션

    귀하의 솔루션은 올바른 것 같습니다 :

    SELECT s.sid, s.name
    FROM Supplier s, Supplies su, Project pr
    WHERE s.sid = su.sid AND su.jid = pr.jid
    GROUP BY s.sid, s.name
    HAVING COUNT (DISTINCT pr.jid) >= 2 
    

    당신은 그렇지 않은 경우의 선택 부분의 일부가 될 수 없습니다, 다음 (이 그룹의 수에 영향을주지 않지만, 당신이 그것을 포함해야하므로 SNAME, 그것은에 기능적으로 의존하는 그룹화 속성으로 SID를 사용하여 세 개의 테이블을 조인 문). 그럼 당신은 당신의 조건을 만족하지 않는 사람들을 제거하십시오 충족의 pr.jid는 원래 싶었다 인> = 2입니다.

    문제에 대한 최선의 해결책

    나는 개인적으로 단순한 청소기 솔루션을 선호 :

     SELECT sid, sname from
        (SELECT sid from supplies 
        GROUP BY sid, pid 
        HAVING count(DISTINCT jid) >= 2
        ) AS T1
    NATURAL JOIN 
    Supliers;
    

    (가) 모든 시간을하지 필요한 경우에만 수행 조인 때문에 그것은 또한, 빠르게 실행하는 것입니다.

    --dmg

  2. ==============================

    2.우리가 계산 같은 집계 함수에 Where 절을 사용할 수 없기 때문에 (), 분 (), SUM () 등 HAVING 절은 SQL에서이 문제를 극복하기 위해 존재로했다 그래서. 이 링크를 통해 절 이동을 가진에 대한 예를 참조

    우리가 계산 같은 집계 함수에 Where 절을 사용할 수 없기 때문에 (), 분 (), SUM () 등 HAVING 절은 SQL에서이 문제를 극복하기 위해 존재로했다 그래서. 이 링크를 통해 절 이동을 가진에 대한 예를 참조

    http://www.sqlfundamental.com/having-clause.php

  3. ==============================

    3.우선, 당신은 오히려 표 1, 표 2 FROM보다 JOIN 구문을 사용해야합니다, 당신이 필요로하는 당신은 항상 작은 필드로로 그룹화를 제한해야합니다.

    우선, 당신은 오히려 표 1, 표 2 FROM보다 JOIN 구문을 사용해야합니다, 당신이 필요로하는 당신은 항상 작은 필드로로 그룹화를 제한해야합니다.

    내가 테스트하지 않았지만, 첫 번째 쿼리는 나에게 벌금을 보이지만로 다시 작성할 수 있습니다 :

    SELECT s.sid, s.name
    FROM 
        Supplier s
        INNER JOIN (
           SELECT su.sid
           FROM Supplies su
           GROUP BY su.sid
           HAVING COUNT(DISTINCT su.jid) > 1
        ) g
            ON g.sid = s.sid
    

    또는 단순화 :

    SELECT sid, name
    FROM Supplier s
    WHERE (
        SELECT COUNT(DISTINCT su.jid)
        FROM Supplies su
        WHERE su.sid = s.sid
    ) > 1
    

    당신은 또한 GROUP BY는 PID해야하기 때문에, 두 번째 쿼리는 나에게 잘못 보인다.

     SELECT s.sid, s.name
        FROM 
            Supplier s
            INNER JOIN (
                SELECT su.sid
                FROM Supplies su
                GROUP BY su.sid, su.pid
                HAVING COUNT(DISTINCT su.jid) > 1
            ) g
                ON g.sid = s.sid
    

    위의 쿼리에서다시피, 나는 INNER는 필터링을 수행하는 조인 구문을 사용하지만 그것은 또한 같이 쓸 수있다 :

    SELECT s.sid, s.name
    FROM Supplier s
    WHERE (
         SELECT COUNT(DISTINCT su.jid)
         FROM Supplies su
         WHERE su.sid = s.sid
         GROUP BY su.sid, su.pid
    ) > 1
    
  4. ==============================

    4.SQL 데이터베이스의 어떤 종류 (MSSQL, 오라클 등)을 사용하고 있습니까? 나는 당신이 쓴 것은 올바른 생각합니다.

    SQL 데이터베이스의 어떤 종류 (MSSQL, 오라클 등)을 사용하고 있습니까? 나는 당신이 쓴 것은 올바른 생각합니다.

    또한이 같은 첫 번째 쿼리를 작성할 수 있습니다 :

    SELECT s.sid, s.name
    FROM Supplier s
    WHERE (SELECT COUNT(DISTINCT pr.jid)
           FROM Supplies su, Projects pr
           WHERE su.sid = s.sid 
               AND pr.jid = su.jid) >= 2
    

    그것은 좀 더 읽기, 그리고 적은 GROUP BY와 함께 할하는 것보다 마음 절곡. 성능은 비록 다를 수 있습니다.

  5. ==============================

    5.적어도 두 개의 서로 다른 프로젝트에 공급되는 부품의 공급 업체에 대한하지 1.Get 공급 업체 번호와 이름.

    적어도 두 개의 서로 다른 프로젝트에 공급되는 부품의 공급 업체에 대한하지 1.Get 공급 업체 번호와 이름.

     SELECT S.SID, S.NAME
     FROM SUPPLIES SP
     JOIN SUPPLIER S
     ON SP.SID = S.SID
     WHERE PID IN
     (SELECT PID FROM SUPPPLIES GROUP BY PID, JID HAVING COUNT(*) >= 2)
    

    나는 두 번째 질문에 대한 취소하고 있지 않다

  6. from https://stackoverflow.com/questions/16327954/using-group-by-and-having-clause by cc-by-sa and MIT license