2016-09-26 3 views
4

나는 다음과 같은 테이블이 있습니다MySQL의 - 계수가 데이터를 선택 1 개 이상의

+-------------------------------------+----------------------------------------------------------------+ 
| keyword        | landing_page             | 
+-------------------------------------+----------------------------------------------------------------+ 
| orange        | https://www.example.co.uk/        | 
| apple        | https://www.example.co.uk/        | 
| pear        | https://www.example.co.uk/        | 
| apple        | https://www.example.co.uk/        | 
| apple        | https://www.example.co.uk/landing-page | 
+-------------------------------------+----------------------------------------------------------------+ 

내가이 예에서, 그래서 우리는 '하나 이상의 별개의 방문 페이지가있는 모든 키워드를 선택하고 싶습니다를 돌아 가기 :

apple, https://www.example.co.uk 
apple, https://www.example.co.uk/landing-page 

어떻게하면 MySQL에서이 작업을 수행 할 수 있습니까?

UPDATE : 나는 다음을 시도했지만 작동하지 않았다 당신이 시도

select keyword, count(landing_page) 
from search_data 
group by keyword 
having count(distinct landing_page) > 1; 
+0

당신이 절 –

+0

@TheOneandOnlyChemistryBlob을 왜 HAVING의 고유 한 카운트하지 않습니다? – Barmar

+0

@Barmar, select *에서 DISTINCT를 사용하여 필터링 할 데이터의 양을 줄이는 것이 어떻습니까? having 절에서 구별되는 경우이 시점 이전에 데이터가 이미 필터링되었을 수 있습니다. –

답변

4

쿼리는 솔루션의 일부입니다. 이 쿼리를 인라인보기로 사용하여 두 개 이상의 방문 페이지가있는 키워드를 식별하십시오. 해당 쿼리의 결과를 원래 테이블로 다시 결합하십시오.

SELECT t.keyword 
    , t.landing_page 
FROM (-- keyword with more than one landing page 
     SELECT r.keyword 
      FROM search_data r 
     GROUP BY r.keyword 
     HAVING COUNT(DISTINCT r.landing_page) > 1 
    ) s 
JOIN search_data t 
    ON t.keyword = s.keyword 
GROUP BY t.keyword, t.landing_page 
ORDER BY t.keyword, t.landing_page 

이 방법이 유일한 방법은 아닙니다. 동일한 결과를 반환하는 다른 쿼리 패턴이 있습니다. 또 다른 방법의 예로서, 동일한 키워드 테이블의 다른 행이 존재하지만, 다른에서 landing_page 확인하는 상호 부질 사용 :

SELECT DISTINCT t.keyword, t.landing_page 
    FROM search_data t 
WHERE EXISTS (SELECT 1 
        FROM search_data r 
       WHERE r.keyword = t.keyword 
        AND NOT (r.landing_page <=> t.landing_page) 
      ) 
ORDER BY t.keyword, t.landing_page 

후속

시범 설정 :

CREATE TABLE search_data (keyword VARCHAR(10), landing_page VARCHAR(80)) 
; 
CREATE INDEX search_data_IX1 ON search_data (keyword, landing_page) 
; 
INSERT INTO search_data (keyword, landing_page) VALUES 
('orange','https://www.example.co.uk/') 
,('apple','https://www.example.co.uk/') 
,('pear','https://www.example.co.uk/') 
,('apple','https://www.example.co.uk/') 
,('apple','https://www.example.co.uk/landing-page') 
; 

쿼리 1

EXPLAIN  
SELECT t.keyword 
    , t.landing_page 
FROM (-- keyword with more than one landing page 
     SELECT r.keyword 
      FROM search_data r 
     GROUP BY r.keyword 
     HAVING COUNT(DISTINCT r.landing_page) > 1 
    ) s 
JOIN search_data t 
    ON t.keyword = s.keyword 
GROUP BY t.keyword, t.landing_page 
ORDER BY t.keyword, t.landing_page 

--  id select_type table  type possible_keys key    key_len ref  rows Extra 
-- ------ ----------- ---------- ------ --------------- --------------- ------- ------ ------ ------------------------ 
--  1 PRIMARY  <derived2> system (NULL)   (NULL)   (NULL) (NULL)  1 
--  1 PRIMARY  t   ref  search_data_IX1 search_data_IX1 13  const  2 Using where; Using index 
--  2 DERIVED  r   index (NULL)   search_data_IX1 96  (NULL)  5 Using index 
을 EXPLAIN

쿼리 실행 한

SELECT t.keyword 
    , t.landing_page 
FROM (-- keyword with more than one landing page 
     SELECT r.keyword 
      FROM search_data r 
     GROUP BY r.keyword 
     HAVING COUNT(DISTINCT r.landing_page) > 1 
    ) s 
JOIN search_data t 
    ON t.keyword = s.keyword 
GROUP BY t.keyword, t.landing_page 
ORDER BY t.keyword, t.landing_page 

-- keyword landing_page 
-- ------- -------------------------------------- 
-- apple https://www.example.co.uk/ 
-- apple https://www.example.co.uk/landing-page 

쿼리 2

EXPLAIN 
SELECT DISTINCT t.keyword, t.landing_page 
    FROM search_data t 
WHERE EXISTS (SELECT 1 
        FROM search_data r 
       WHERE r.keyword = t.keyword 
        AND NOT (r.landing_page <=> t.landing_page) 
      ) 
ORDER BY t.keyword, t.landing_page 

--  id select_type   table type possible_keys key    key_len ref    rows Extra 
-- ------ ------------------ ------ ------ --------------- --------------- ------- -------------- ------ ------------------------------------- 
--  1 PRIMARY    t  range (NULL)   search_data_IX1 96  (NULL)    6 Using where; Using index for group-by 
--  2 DEPENDENT SUBQUERY r  ref  search_data_IX1 search_data_IX1 13  test.t.keyword  1 Using where; Using index 

설명 쿼리 실행이

SELECT DISTINCT t.keyword, t.landing_page 
    FROM search_data t 
WHERE EXISTS (SELECT 1 
        FROM search_data r 
       WHERE r.keyword = t.keyword 
        AND NOT (r.landing_page <=> t.landing_page) 
      ) 
ORDER BY t.keyword, t.landing_page 

-- keyword landing_page 
-- ------- -------------------------------------- 
-- apple https://www.example.co.uk/ 
-- apple https://www.example.co.uk/landing-page 
+0

두 쿼리가 모두 응답하지 않는 것 같습니다. – Adders

+1

쿼리가 "중단"되면이 테이블에 많은 수의 행이 있거나 MySQL에서 인덱스를 효과적으로 사용하지 못하거나 적합한 인덱스를 사용할 수 없다는 의미입니다. 성능 진단을 위해 실행 계획을 보려면 EXPLAIN으로 시작합니다. MySQL은 인덱스'ON search_data (keyword, landing_page) '를 효과적으로 사용할 것으로 기대합니다. 이상적으로, MySQL은 GROUP BY에 필요한 작업에 "Using filesort"가 아닌 "Using index"가 될 것입니다. 테이블이 매우 큰 경우 WHERE 절을 추가하여 행 수를 제한하려고합니다. – spencer7593

관련 문제