쿼리 : 항목 당 여러 집계를 계산합니다
-
07-07-2019 - |
문제
종종 데이터베이스 항목 목록과 각 항목에 대한 특정 집계 번호를 표시해야합니다. 예를 들어, 스택 오버플로에 제목 텍스트를 입력하면 관련 질문 목록이 나타납니다. 이 목록은 관련 항목의 제목과 각 제목에 대한 단일 집계 된 수량의 응답 수를 보여줍니다.
비슷한 문제가 있지만 여러 집계가 필요합니다. 사용자 옵션에 따라 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를 처리합니다.