2016-09-26 39 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,爲什麼不選擇DISTINCT來減少要過濾的數據量?如果你在你的子句中區分數據可能已經在此點之前被過濾了 –

回答

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') 
; 

EXPLAIN查詢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 

執行查詢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

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 

執行查詢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將「使用索引」而不是「使用filesort」用於GROUP BY所需的操作。如果表格非常大,我們可能想要添加WHERE子句來限制行數。 – spencer7593