Mysql

如何查詢維基百科的數據庫以檢索給定標題的主題和表面形式?

  • January 1, 2017

首先,這裡有維基百科的數據庫方案圖。我在本地使用了他們的一個轉儲來使用它。

現在,我需要一個 MySQL 查詢來檢查具有給定輸入“Dog_breeder”或“Dog_breeding”的表pageredirect我想獲取連結到此輸入的兩種類型頁面的列表。

例如,Dog_breeding 是一個主要主題,以下頁面將重定向到它:

  • Dog_Breeder
  • Dog_breeder
  • Dog_breeders
  • 螺柱狗

在數據庫中,它以這種方式儲存:

|---------------------------|       |---------------------------|
| table: page               |       | table: redirect           |
|---------------------------|       |---------------------------|
| page_id   | page_title    |       | rd_from   | rd_title      |
|---------------------------|       |---------------------------|
| 476072    | Dog_breeding  |       | 796236    | Dog_breeding  |
| 796236    | Dog_breeder   |       | 16274701  | Dog_breeding  |
| 16274701  | Dog_breeders  |       | 37353772  | Dog_breeding  |
| 37353772  | Stud_dog      |       | 40738352  | Dog_breeding  |
| 40738352  | Dog_Breeder   |       |---------------------------|
| 11606599  | Dog_breeders  |       
| 22534134  | Dog_breeders  |       
|---------------------------|       

所以所有頁面都在page表中,然後重定向儲存在redirect表中(rd_from是將重定向到首頁的rd_title頁面)

我有一個查詢來檢索一個主題的所有重定向條目:

SELECT 
   page_id, 
   page_title, 
   rd_from,
   rd_title
FROM 
   redirect 
   JOIN page ON page_id = rd_from
WHERE rd_title = 'Dog_breeding'

但是有兩個問題:

  1. 它沒有給我首頁本身(‘Dog_breeding’)
  2. 如果我WHERE rd_title = 'Dog_breeder'說它什麼都找不到…

Dog_breeding無論輸入是or ,我都想得到類似下面的東西Dog_breeder

page_id     | page_title    | rd_from   | rd_title  
-------------------------------------------------------
476072      | Dog_breeding  |           | 
796236      | Dog_breeder   | 796236    | Dog_breeding
16274701    | Dog_breeders  | 16274701  | Dog_breeding
37353772    | Stud_dog      | 37353772  | Dog_breeding
40738352    | Dog_Breeder   | 40738352  | Dog_breeding

我想我可以用 PHP 和數據庫來回做幾個(檢查它是否是主題,如果不是抓住主題,然後像我上面那樣查詢),但我覺得有一個查詢解決方案?

最初,通過向 WHERE 子句添加新標準來解決這個問題似乎很容易。

SELECT 
   page.page_id, 
   page.page_title, 
   redirect.rd_from,
   redirect.rd_title
FROM 
   redirect 
   JOIN page ON page.page_id = redirect.rd_from
WHERE 
   redirect.rd_title = 'Dog_breeding' or page.page_title = 'Dog_breeding'

但正如 Lazhar 所指出的,這僅適用於請求的文本屬於主 wiki 頁面,而不適用於重定向頁面。

查看表定義後:

MediaWiki - 手冊:頁表

page_is_redirect 這裡的值為 1 表示文章是重定向;在所有其他情況下為 0

MediaWiki - 手冊:重定向表

包含目前為重定向的每個頁面(即,不包含重定向的舊版本)源頁面的 id 和有關目標的資訊。目標頁面可能存在也可能不存在。

我決定使用這個欄位來解決這個問題。

首先我們需要知道首頁的標題,即不是重定向的頁面。在這個問題中:Dog_breeding

select page.page_title as title from page where page.page_title = 'Dog_breeders' and page_is_redirect = 0
union
select redirect.rd_title as title 
from redirect 
where redirect.rd_from in (select page.page_id from page where page.page_title = 'Dog_breeders' and page_is_redirect = 1) 

然後使用第一種方法:

SELECT 
   page.page_id, 
   page.page_title, 
   redirect.rd_from,
   redirect.rd_title
FROM 
   page 
   left JOIN redirect ON page.page_id = redirect.rd_from
   join (select page.page_title as title from page where page.page_title = 'Dog_breeders' and page_is_redirect = 0
         union
         select redirect.rd_title as title 
         from redirect 
         where redirect.rd_from in (select page.page_id from page where page.page_title = 'Dog_breeders' and page_is_redirect = 1) 
         ) cteTitle 
WHERE 
   redirect.rd_title = cteTitle.title or page.page_title = cteTitle.title;

這是結果:

+----------+--------------+----------+--------------+
|  page_id |  page_title  |  rd_from |   rd_title   |
+----------+--------------+----------+--------------+
|  796236  |  Dog_breeder |  796236  | Dog_breeding |
+----------+--------------+----------+--------------+
| 16274701 | Dog_breeders | 16274701 | Dog_breeding |
+----------+--------------+----------+--------------+
| 37353772 |   Stud_dog   | 37353772 | Dog_breeding |
+----------+--------------+----------+--------------+
| 40738352 |  Dog_Breeder | 40738352 | Dog_breeding |
+----------+--------------+----------+--------------+
|  476072  | Dog_breeding |   NULL   |     NULL     |
+----------+--------------+----------+--------------+

可以在這裡查看:http ://rextester.com/OQMV97513

注意:在SO中還有另一種使用pagelinks表的解決方案

引用自:https://dba.stackexchange.com/questions/159686