我有一个填充了大量“空”记录的数据库,我想摆脱那些孤立的记录。
数据库结构如下;
| 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 ''
但是这个查询只获取(空)“子”行,而不是它们的“父”行。
有两个逻辑条件将父级绑定到子级;
有没有办法创建一个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 :(得分: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
在关系数据库中,没有“after”或“before”之类的概念,除非您自己定义并将数据添加到实现该概念的表中(如datetimestamp,或顺序增加数字键,或其他。)这样的工件,关系数据库表中的记录 不 有任何隐含的顺序。
答案 1 :(得分: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.";
}
?>