2017-01-23 45 views
1

我有一個數據庫充滿了大量的「空」記錄,我想擺脫那些孤兒記錄。SQL - 在一個查詢中同時選擇「子」和「父」行

數據庫是這樣構成的;

  1. 包含真實項目(meta_value)
  2. 那就是 「鏈接」 到它的孩子父行(由它的meta_key)

一個子行 | meta_id post_id meta_key meta_value | | | | 011 301 ACF__P_01_01 Foo | | 012 309 _ACF__P_01_01 field_5874d5 | | 013 321 ACF__P_01_02 | | 014 316 _ACF__P_01_02 field_54290a | | 015 119 ACF__P_01_03 Bar | | 016 101 _ACF__P_01_03 field_a04a88 | | 017 119 ACF__P_01_03 | | 018 101 _ACF__P_01_03 field_a04a88 | | 019 149 ACF__P_01_03 | | 020 111 _ACF__P_01_03 field_a04a88 | | 021 169 ACF__P_01_03 Foo Bar | | 022 171 _ACF__P_01_03 field_a04a88 |


用這樣的查詢很容易選擇所有(空)「子」行;

SELECT 
    * 
FROM 
    wp_postmeta 
WHERE 
    wp_postmeta.meta_key LIKE '%ACF__%' 
AND 
    wp_postmeta.meta_value LIKE '' 

但是,這個查詢只提取(空)「子」行,而不是它們的「父」行。


有兩個邏輯條件將父項綁定到子項;

  1. 第一行永遠是孩子,立即由其父隨後
  2. 父行具有相同的「meta_key」值,因爲它是子級,但由下劃線預先修正。

有什麼方法來創建選擇空的子記錄一個SQL查詢(像我上面那樣)它的父呢?我可以運行兩個查詢(第一個獲取父項,第二個獲取空白子項,我猜)。我更喜歡單個查詢來獲取它們 - 但是當這不可能時,我可以運行兩個查詢(第一個獲取父項,第二個獲取空白子項,我猜)。

我使用Navicat爲我的數據庫管理,所以它必須是普通的SQL - 沒有PHP。


查詢應該吐出這樣的結果;


| meta_id post_id meta_key meta_value | | | | 013 321 ACF__P_01_02 | | 014 316 _ACF__P_01_02 field_54290a | | 017 119 ACF__P_01_03 | | 018 101 _ACF__P_01_03 field_a04a88 | | 019 149 ACF__P_01_03 | | 020 111 _ACF__P_01_03 field_a04a88 |


所以無論是空的,孩子的(在「meta_value」沒有值)和它的父(兩者具有相同的「meta_key」,這裏的家長有下劃線。

+0

看起來像父行總是有一個meta_value,爲什麼不在你的where子句中使用它? 其中(wp_postmeta.meta_key LIKE '%ACF __%' AND wp_postmeta.meta_value LIKE '')或(wp_postmeta.meta_key LIKE '%ACF __%' AND wp_postmeta.meta_value <> '');然後根據您的喜好對輸出進行排序 – iLikeMySql

+0

您想要的結果如何(請給出上述問題中的數據示例)? –

+0

你知道Navicat是否有共同的表格表達? –

回答

3

隨着自聯接

Select * 
from wp_postmeta c 
    join wp_postmeta p 
     on p.meta_key = '_' + c.meta_key 

以上纔會取的親子記錄「對」。如果有可能有父母沒有子女(我認爲這是不可能有孩子沒有父母),並且希望所有的家長,包括無子女的,可以使用外連接

Select * 
from wp_postmeta p 
    left join wp_postmeta c 
     on '_' + c.meta_key = p.meta_key 

在關係數據庫中,有沒有「之後」或「之前」這樣的概念,除非你自己定義它,並將數據添加到實現該概念的表中(如日期時間戳,或順序增加數字鍵或其他),如果沒有這些工件,關係數據庫表中的記錄做不是有任何隱式的順序

+0

看起來很有前途;它會顯示來自我的表格的所有記錄並帶有下劃線。 但我必須像我在我的初始職位過濾它們(字段必須包含「ACF__」並且也是空的)。 我可以使用這些過濾器進行查詢並將它們連接到父級? '''SELECT \t * FROM \t wp_postmeta WHERE \t wp_postmeta.meta_key LIKE '%ACF __%' AND wp_postmeta.meta_value LIKE '' C JOIN wp_postmeta P於p.meta_key = '_' + C .meta_key''' 這會導致錯誤; '''你的SQL語法錯誤'c JOIN wp_postmeta p ON p.meta_key ='_'+ c.meta_key'at line 7''' –

+0

然後,你應該谷歌'加入'並閱讀在上面。你修改後的查詢在語法上不正確地使用了join,'Join'是數據庫查詢的基本工具,直到你學會使用它,你纔會花費更多時間學習它。 。再看看輸出,它應該顯示來自表的父子記錄的所有*對*行(每個*對*在單個顯示的輸出行中)。 –

+0

我嘗試了兩個例子,但它返回大約25000行 - 因爲它們根本沒有被過濾(當我用「foo」之類的東西替換「_」時,我得到了相同的25000結果)......看起來它什麼都不做。 –

0

使用PHP我能解決它。我迭代查詢的第一個結果(取得所有空的子元素),並在循環內部獲取子元素後面的每一行。

但是,這是PHP - 我想純SQL :)

<?php 

$connection = new mysqli(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME); 

    if ($connection -> connect_errno > 0) { 

    die ("Unable to connect to database [" . $connection->connect_error . "]"); 

    } 

$query_1 = "SELECT * FROM `wp_postmeta` WHERE `meta_key` LIKE '%ACF%__' AND `meta_value` LIKE ''"; 

    if (!$result_1 = $connection -> query($query_1)) { 

    die ("There was an error running query[" . $connection -> error . "]"); 

    } 

    if ($result_1) { 

    $i = 0; 

    echo "<h2>ACF - empty fields</h2>"; 
    echo "<table border=1 cellpadding=4 cellspacing=0 width=800>"; 
    echo "<tr style='background:#eee;font-weight:bold;'><td>row</td><td>meta_id</td><td>post_id</td><td>meta_key</td><td>meta_value</td></tr>"; 

     while ($row_1 = $result_1 -> fetch_assoc()) { 

     $i++; 
     echo "<tr>"; 
     echo "<td width=100>" . sprintf('%03d', $i) . "</td>"; 
     echo "<td width=100 style='background:#aaa;color:#fff;font-weight:bold;'>" . $row_1["meta_id"] . "</td>"; 
     echo "<td width=100>" . $row_1["post_id"] . "</td>"; 
     echo "<td width=100>" . $row_1["meta_key"] . "</td>"; 
     echo "<td width=500>" . $row_1["meta_value"] . "</td>"; 
     echo "</tr>"; 

     $query_2 = "SELECT * FROM `wp_postmeta` WHERE `meta_id` = " . ($row_1["meta_id"] + 1); 

      if (!$result_2 = $connection -> query($query_2)) { 

      die ("There was an error running query[" . $connection -> error . "]"); 

      } 

      while ($row_2 = $result_2 -> fetch_assoc()) { 

      $i++; 
      echo "<tr>"; 
      echo "<td width=100>" . sprintf('%03d', $i) . "</td>"; 
      echo "<td width=100 style='background:#aaa;color:#fff;font-weight:bold;'>" . $row_2["meta_id"] . "</td>"; 
      echo "<td width=100>" . $row_2["post_id"] . "</td>"; 
      echo "<td width=100>" . $row_2["meta_key"] . "</td>"; 
      echo "<td width=500>" . $row_2["meta_value"] . "</td>"; 
      echo "</tr>"; 

      } 

     mysqli_free_result($result_2); 

     } 

    mysqli_free_result($result_1); 

    echo "</table>"; 

    } else { 

    echo "No entries found."; 

    } 

?> 

- 編輯 -

這PHP代碼比較好,我想......它僅使用2在查詢和迭代第一個...

它完美,但仍是不純粹的SQL - 我想擺脫PHP的...

<?php 

/* --------------------------------------------------- */ 

$connection = new mysqli(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME); 

    if ($connection -> connect_errno > 0) { 

    die ("Unable to connect to database [" . $connection->connect_error . "]"); 

    } 

/* --------------------------------------------------- */ 

$query = "SELECT `meta_id` FROM `wp_postmeta` WHERE `meta_key` LIKE '%ACF%__' AND `meta_value` LIKE ''"; 

    if (!$result = $connection -> query($query)) { 

    die ("There was an error running query[" . $connection -> error . "]"); 

    } 

    if ($result) { 

    $array = array(); 

     while ($row = $result -> fetch_assoc()) { 

     $array[] = $row["meta_id"]; 
     $array[] = $row["meta_id"] + 1; 

     } 

    mysqli_free_result($result); 

/* --------------------------------------------------- */ 

    $query = "SELECT * FROM `wp_postmeta` WHERE `meta_id` IN (" . implode(",", array_map("intval", $array)) . ")"; 

     if (!$result = $connection -> query($query)) { 

     die ("There was an error running query[" . $connection -> error . "]"); 

     } 

     if ($result) { 

     $i = 0; 

     echo "<h2>ACF - empty fields</h2>"; 
     echo "<table>"; 
     echo "<tr><td>record</td><td>meta_id</td><td>post_id</td><td>meta_key</td><td>meta_value</td></tr>"; 

      while ($row = $result -> fetch_assoc()) { 

      $i++; 
      echo "<tr>"; 
      echo "<td>" . sprintf('%03d', $i) . "</td>"; 
      echo "<td>" . $row["meta_id"] . "</td>"; 
      echo "<td>" . $row["post_id"] . "</td>"; 
      echo "<td>" . $row["meta_key"] . "</td>"; 
      echo "<td>" . $row["meta_value"] . "</td>"; 
      echo "</tr>"; 

      } 

     mysqli_free_result($result); 

     echo "</table>"; 

      if (isset($_GET["delete"])) { 

      echo "<span>all records deleted</span>"; 

      } else { 

      echo "<a href='?delete'>delete empty records</a>"; 

      } 

     } 

/* --------------------------------------------------- */ 

    } else { 

    echo "No entries found."; 

    } 

?> 
相關問題