0

我在 MySQL 数据库中有一个表,其中包含以下列:

itemID      bigint(11)
itemDate    datetime    
attributeID smallint(6)
value       int(9)

编辑:此表存储在一个单独的表中唯一定义的项目的属性,其主键和关系键是itemID

最好删除的 SQL 查询 (?) 是什么从最近的记录开始到最旧的记录):

  • 此表中= 0(如果存在)的每条记录(具有相同itemID和相同属性ID且>5 且itemDate为(较旧但也是最新)或相同的另一条记录)

  • 此表中的每条记录(如果存在)(具有相同itemID和相同attributeID和相同的另一条记录,并且itemDate是(较旧但也是最近的)或相同)

也见最后的代码

我在 PHP 脚本中使用它。

基本上,我有多余的数据,因为我没有尽快发现它没有填充大约 100k 条目的错误。下面是一个非常小的例子:

itemID  itemDate        attributeID value
28  11.09.2013 2:00     4           0
28  11.09.2013 2:00     5           0
28  11.09.2013 2:01     1           0
28  11.09.2013 2:01     2           0
28  11.09.2013 2:01     3           0
28  11.09.2013 2:01     4           0
28  11.09.2013 2:01     5           0
28  11.09.2013 2:02     1           21
28  11.09.2013 2:02     2           11
28  11.09.2013 2:02     3           4
28  11.09.2013 2:02     1           21
28  11.09.2013 2:02     2           11
28  11.09.2013 2:02     3           4
28  11.09.2013 2:02     1           21
28  11.09.2013 2:02     2           12
28  11.09.2013 2:02     3           4
28  13.09.2013 18:54    1           0
28  13.09.2013 18:54    2           0
28  13.09.2013 18:54    3           0
28  13.09.2013 18:55    1           21
28  13.09.2013 18:55    2           12
28  13.09.2013 18:55    3           6

上面应该变成(删除算法的多次迭代后):

itemID  itemDate        attributeID value
28  11.09.2013 2:00     4           0
28  11.09.2013 2:00     5           0
28  11.09.2013 2:01     1           0
28  11.09.2013 2:01     2           0
28  11.09.2013 2:01     3           0
28  11.09.2013 2:02     1           21
28  11.09.2013 2:02     2           11
28  11.09.2013 2:02     3           4
28  11.09.2013 2:02     2           12
28  13.09.2013 18:55    3           6

我希望我足够清楚地定义了问题,但是,如果我应该澄清任何事情,请告诉我。非常感谢你!

更新

我设法找到了一个结合 SQL 和 php 的解决方案,但我不太喜欢它。我确实相信通过 2 个正确的 SQL 查询可以获得相同的结果,因此,尽管我很满意我有办法清理我的数据库,但问题仍然存在:如何将下面的代码转换为纯 sql 查询。

// Properties
$item_found_count = $item_valid_count = 0;

// Find zero value entries
$query = "SELECT * FROM $db_fb WHERE value = '0'";

if ($result = mysqli_query($connection, $query)) {

    // for each record found
    while($row = $result->fetch_array()) {

        $item_found_count++;    // Count all items found
        $t_itemID = $row['itemID']; $t_itemDate = $row['itemDate']; $t_attributeID = $row['attributeID'];   // Record this data just in case we need it as a 'pointer' to delete the record

        //echo "Entry found: " . $row['itemID'] . " " . $row['itemDate'];

        $query = "SELECT * FROM $db_fb WHERE itemID = $t_itemID AND itemDate < '$t_itemDate' AND attributeID = '$t_attributeID' AND value > '5' ORDER BY itemDate DESC LIMIT 1";
        // If there is such an entry, the current one must be deleted.
        if ($SecondResult = mysqli_query($connection, $query)) {

            while($rowSpec = $SecondResult->fetch_array()) {
            $item_valid_count++;    // Count all items actually deleted

                //echo "<br>-> mark;"; print_r($rowSpec); echo "<br>";

                // Delete if ID, itemDate, attributeID and VALUE coincide
                $q_del = "DELETE FROM $db_fb WHERE itemID = $t_itemID AND itemDate = '$t_itemDate' AND attributeID = '$t_attributeID' AND value = '0'";
                $deleteRes = mysqli_query($connection, $q_del);

            }

        }

        //echo "--------------------------<br><br>";
    }

}

// Select from table where values are identical, attributeID identical, ID identical, itemDates immediately consecutive LIMIT by 2. Delete most recent entry.
$query = "SELECT MAX(itemDate) as itemDate, itemID, attributeID, value, count(*) FROM $db_fb GROUP BY itemID, attributeID, value HAVING count(*) > 1 ORDER BY itemDate DESC";

    if ($ThirdResult = mysqli_query($connection, $query)) {

            while($rowSpec = $ThirdResult->fetch_array()) {
            $item_duplicates_count++;   // Count all items actually deleted

                $t_itemID = $rowSpec['itemID']; $t_itemDate = $rowSpec['itemDate']; $t_attributeID = $rowSpec['attributeID'];   $t_value = $rowSpec['value']; // Record this data just in case we need it as a 'pointer' to delete the record

                //echo "<br>-> mark;"; print_r($rowSpec); echo "<br>";
                $q_del = "DELETE FROM $db_fb WHERE itemID = '$t_itemID' AND itemDate = '$t_itemDate' AND attributeID = '$t_attributeID' AND value = '$t_value'";
                $deleteRes = mysqli_query($connection, $q_del);


            }

        }

echo "Zeroed found: " . $item_found_count . "<br>";
echo "Zeroed valid for deletion: " . $item_valid_count . "<br>";
echo "Zeroed remaining: " . ($item_found_count - $item_valid_count) . "<br>";

echo "Consecutive duplicates: " . $item_duplicates_count;
4

0 回答 0