문제

종종 데이터베이스 항목 목록과 각 항목에 대한 특정 집계 번호를 표시해야합니다. 예를 들어, 스택 오버플로에 제목 텍스트를 입력하면 관련 질문 목록이 나타납니다. 이 목록은 관련 항목의 제목과 각 제목에 대한 단일 집계 된 수량의 응답 수를 보여줍니다.

비슷한 문제가 있지만 여러 집계가 필요합니다. 사용자 옵션에 따라 3 가지 형식의 항목 목록을 표시하고 싶습니다.

  • 내 항목의 이름 (총 15 개, 13 명은 나에 의해 소유)
  • 내 항목 이름 (총 15 개)
  • 내 항목 이름 (13 소유자)

내 데이터베이스는 다음과 같습니다.

  • 항목: itemId, itemName, 소유자
  • 카테고리: catid, catname
  • 지도: mapid, itemid, catid

아래의 쿼리는 다음과 같은 것입니다 : 카테고리 이름, 카테고리 당 항목 ID 수 카운트

SELECT
  categories.catName,
  COUNT(map.itemId) AS item_count
FROM categories
LEFT JOIN map
  ON categories.catId = map.catId
GROUP BY categories.catName

이 사람은 카테고리 이름,이 소유자에 대한 카테고리 당 항목 ID 수 카운트

SELECT categories.catName, 
COUNT(map.itemId) AS owner_item_count
FROM categories
LEFT JOIN map
  ON categories.catId = map.catId
LEFT JOIN items
  ON items.itemId = map.itemId
WHERE owner = @ownerId
GROUP BY categories.catId

그러나 단일 쿼리에서 동시에 동시에 가져 오는 방법은 무엇입니까? IE : 카테고리 이름, 카테고리 당 항목 ID 수,이 소유자의 범주 당 항목 ID 수 카운트

보너스. catid count! = 0이 무엇보다 선택적으로 검색하려면 어떻게해야합니까? "Where item_count <> 0"을 시도하면 다음과 같습니다.

MySQL said: Documentation
#1054 - Unknown column 'rid_count' in 'where clause' 
도움이 되었습니까?

해결책

다음은 트릭입니다 : 계산 a SUM() 1 또는 0 인 것으로 알려진 값의 COUNT() 값이 1 인 행 중에서 부울 비교가 1 또는 0 (또는 null)을 반환한다는 것을 알고 있습니다.

SELECT c.catname, COUNT(m.catid) AS item_count,
  SUM(i.ownerid = @ownerid) AS owner_item_count
FROM categories c
  LEFT JOIN map m USING (catid)
  LEFT JOIN items i USING (itemid)
GROUP BY c.catid;

보너스 질문은 단순히 외부 조인 대신 내부 조인을 할 수 있습니다. 이는 적어도 하나의 행이있는 범주만을 의미합니다. map 반환됩니다.

SELECT c.catname, COUNT(m.catid) AS item_count,
  SUM(i.ownerid = @ownerid) AS owner_item_count
FROM categories c
  INNER JOIN map m USING (catid)
  INNER JOIN items i USING (itemid)
GROUP BY c.catid;

다음은 효율적이지는 않지만 오류가 발생한 이유를 설명하기 위해 보여 드리겠습니다.

SELECT c.catname, COUNT(m.catid) AS item_count,
  SUM(i.ownerid = @ownerid) AS owner_item_count
FROM categories c
  LEFT JOIN map m USING (catid)
  LEFT JOIN items i USING (itemid)
GROUP BY c.catid
HAVING item_count > 0;

열 별칭을 사용할 수 없습니다 WHERE 절의 표현이기 때문에 절 WHERE 절은 선택 목록의 표현식 전에 평가됩니다. 다시 말해, 선택 목록 표현식과 관련된 값은 아직 사용할 수 없습니다.

당신은에서 열 별명을 사용할 수 있습니다 GROUP BY, HAVING, 그리고 ORDER BY 조항. 이 조항은 선택 목록의 모든 표현이 평가 된 후에 실행됩니다.

다른 팁

sum () 안에 사례 명세서를 몰래 넣을 수 있습니다.

SELECT categories.catName, 
    COUNT(map.itemId) AS item_count,
    SUM(CASE WHEN owner= @ownerid THEN 1 ELSE 0 END) AS owner_item_count
FROM categories
LEFT JOIN map  ON categories.catId = map.catId
LEFT JOIN items  ON items.itemId = map.itemId
GROUP BY categories.catId
HAVING COUNT(map.itemId) > 0
SELECT categories.catName, 
  COUNT(map.itemId) AS item_count,
  COUNT(items.itemId) AS owner_item_count
FROM categories
INNER JOIN map
  ON categories.catId = map.catId
LEFT JOIN items
  ON items.itemId = map.itemId
  AND items.owner = @ownerId
GROUP BY categories.catId

사용할 수 있습니다 HAVING 조항 on owner_item_count, 그러나 내부 조인은 당신을 위해 item_count를 처리합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top