2014-11-23 2 views
1

에서 집계 나는 두 테이블 내가 인상의 합을 가지고 계산과 별개 device_ids 클릭 캠페인 및 광고주 수준에서 집계되는보고 싶은 MySQL의 쿼리 : 두 개의 서로 다른 수준의

mysql> select * from report; 
+----+----------+------------+------------------+-------------+ 
| id | campaign | advertiser | impression_count | click_count | 
+----+----------+------------+------------------+-------------+ 
| 1 | camp1 | adv1  |    20 |   6 | 
| 2 | camp2 | adv2  |    10 |   2 | 
| 3 | camp1 | adv1  |    15 |   3 | 
| 4 | camp2 | adv2  |    6 |   1 | 
+----+----------+------------+------------------+-------------+ 
4 rows in set (0.00 sec) 

mysql> select * from device; 
+-----------+-----------+ 
| report_id | device_id | 
+-----------+-----------+ 
|   1 | d1  | 
|   1 | d2  | 
|   2 | d1  | 
|   2 | d3  | 
|   2 | d4  | 
|   3 | d2  | 
|   3 | d4  | 
|   4 | d3  | 
|   4 | d4  | 
|   4 | d5  | 
+-----------+-----------+ 
10 rows in set (0.00 sec) 

있습니다. 그래서 아래 쿼리를 작성했습니다.

mysql> select campaign,advertiser,sum(impression_count),sum(click_count),count(distinct device_id) from report LEFT JOIN device ON report.id=device.report_id group by campaign,advertiser; 
+----------+------------+-----------------------+------------------+---------------------------+ 
| campaign | advertiser | sum(impression_count) | sum(click_count) | count(distinct device_id) | 
+----------+------------+-----------------------+------------------+---------------------------+ 
| camp1 | adv1  |     70 |    18 |       3 | 
| camp2 | adv2  |     48 |    9 |       4 | 
+----------+------------+-----------------------+------------------+---------------------------+ 

여기서는 조인 횟수와 click_count가 여러 행에 대해 집계 되었기 때문에 여기에 씁니다. 무엇 원하는 것은

+----------+------------+-----------------------+------------------+---------------------------+ 
| campaign | advertiser | sum(impression_count) | sum(click_count) | count(distinct device_id) | 
+----------+------------+-----------------------+------------------+---------------------------+ 
| camp1 | adv1  |     35 |    9 |       3 | 
| camp2 | adv2  |     16 |    3 |       4 | 
+----------+------------+-----------------------+------------------+---------------------------+ 

http://sqlfiddle.com/#!2/05dd9d/1

이 너무 좋지 않다 솔루션을

select campaign,advertiser,ic,cc,count(distinct device_id) 
from (
    select 
     group_concat(id) as id, 
     sum(impression_count)as ic, 
     sum(click_count)as cc, 
     campaign,advertiser 
    FROM report har GROUP BY campaign,advertiser) a 
    LEFT JOIN device dr ON FIND_IN_SET(dr.report_id, a.id) 
    group by a.id 
); 

발견하지만이 GROUP_CONCAT 결과의 아이폰에이 큰 경우 문제가 발생할 수 있으므로 그룹 CONCAT를 사용합니다.

+0

[SQL 바이올린]에서 테이블 스키마를 업데이트하십시오 (http://sqlfiddle.com/) –

답변

3

싶은 것은 두 가지 쿼리를 수행하고, 그 결과 세트를 가입 할 수 있습니다. 외부 선택은 우리가 실제로 원하는 정보를 선택하고 두 개의 임시 테이블을 공통 값으로 조인하는 것입니다. 전체 캠페인에 대해 기기 테이블에있는 고유 한 기기를 선택하지 않으려는 경우 id 및 report_id를 사용하여이 작업을 수행 할 수 있습니다.

select `firsttable`.campaign, `firsttable`.advertiser, a, b, c from 
    (select id, campaign, advertiser, sum(impression_count) as a, sum(click_count) as b 
    from report 
    group by campaign, advertiser 
) as firsttable 
    left join 
    (select campaign, advertiser, count(distinct device_id) as c 
    from device, report 
    where id=report_id 
    group by campaign, advertiser 
) as secondtable on `firsttable`.campaign=`secondtable`.campaign and 
         `firsttable`.advertiser=`secondtable`.advertiser; 

SQLFiddle :

| ID | CAMPAIGN | ADVERTISER | A | B | 
|----|----------|------------|-----|-----| 
| 1 | camp1 |  adv1 | 35 | 9 | 
| 5 | camp1 |  adv2 | 900 | 900 | 
| 2 | camp2 |  adv2 | 16 | 3 | 

| CAMPAIGN | ADVERTISER | C | 
|----------|------------|---| 
| camp1 |  adv1 | 3 | 
| camp2 |  adv2 | 4 | 

결과 :

| CAMPAIGN | ADVERTISER | A | B |  C | 
|----------|------------|-----|-----|--------| 
| camp1 |  adv1 | 35 | 9 |  3 | 
| camp1 |  adv2 | 900 | 900 | (null) | 
| camp2 |  adv2 | 16 | 3 |  4 | 

,691,363 http://sqlfiddle.com/#!2/8bd63/20

이 쿼리는이 두 임시 테이블의 조합210

쿼리의 문제는 보고서 테이블을 장치 테이블과 결합 할 때 행이 중복된다는 것입니다.

| CAMPAIGN | ADVERTISER | IMPRESSION_COUNT | CLICK_COUNT | DEVICE_ID | 
|----------|------------|------------------|-------------|-----------| 
| camp1 |  adv1 |    20 |   6 |  d1 | 
| camp1 |  adv1 |    20 |   6 |  d2 | 
| camp2 |  adv2 |    10 |   2 |  d1 | 
| camp2 |  adv2 |    10 |   2 |  d3 | 
| camp2 |  adv2 |    10 |   2 |  d4 | 
| camp1 |  adv1 |    15 |   3 |  d2 | 
| camp1 |  adv1 |    15 |   3 |  d4 | 
| camp2 |  adv2 |    6 |   1 |  d3 | 
| camp2 |  adv2 |    6 |   1 |  d4 | 
| camp2 |  adv2 |    6 |   1 |  d5 | 
| camp1 |  adv2 |    900 |   900 | (null) | 
0

아마도이 작업을 수행하는 데 도움을줍니다

SELECT 
    campaign, 
    advertiser, 
    SUM(impression_count) AS ic, 
    sum(click_count) as cc, 
    (select 
      count(distinct device_id) 
     from 
      device 
     where 
      report_id = id) AS DD 
from 
    report 
group by campaign , advertiser; 
+0

이 2로 DD를 반환하고 필요한 각각 3은 3과 :이 같은 끝낼 것 4 – sunilsurana

+0

이 작업은하지만 보고서에서 FIND_IN_SET (report_id, group_concat (id))) AS DD가있는 장치에서 그룹 concatSELECT 캠페인, 광고주, SUM (impression_count) AS ic, sum (click_count) 캠페인, 광고주별로 그룹화; – sunilsurana

관련 문제