2016-09-26 6 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 | 
+-------------------------------------+----------------------------------------------------------------+ 

をd戻り値:

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

あなたのHAVING句 –

+0

@TheOneandOnlyChemistryBlobに明確なカウントされませんなぜいけないのでしょうか? – 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

実行クエリ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 

を説明する1

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

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

関連する問題