如何从MySQL表中删除具有不同日期的冗余记录
我在MySQL数据库中有一个由以下列组成的表:如何从MySQL表中删除具有不同日期的冗余记录,mysql,sql,database,redundancy,Mysql,Sql,Database,Redundancy,我在MySQL数据库中有一个由以下列组成的表: itemID bigint(11) itemDate datetime attributeID smallint(6) value int(9) 编辑:此表存储在单独表中唯一定义的项的属性,该表的主键和关系键为itemID 最好删除的SQL查询(?)是什么(从最新记录到最旧记录): 如果存在,则此表中每个记录的值=0(另一个记录具有相同的项目ID和相同的属性ID,并且具有值>5且项目日期是(较旧但也是最新的)
itemID bigint(11)
itemDate datetime
attributeID smallint(6)
value int(9)
编辑:此表存储在单独表中唯一定义的项的属性,该表的主键和关系键为itemID
最好删除的SQL查询(?)是什么(从最新记录到最旧记录):
- 如果存在,则此表中每个记录的值=0(另一个记录具有相同的项目ID和相同的属性ID,并且具有值>5且项目日期是(较旧但也是最新的)或相同的)
- 此表中的每条记录如果存在(另一条记录具有相同的itemID和相同的attributeID和相同的值,并且itemDate是(较旧但也是最近的)或相同的)
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
上述内容应为(在多次迭代删除算法后):
我希望我对问题的定义足够清楚,但是,如果我需要澄清什么,请告诉我。
谢谢你
更新
我设法找到了一个结合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;
//属性
$item\u found\u count=$item\u valid\u count=0;
//查找零值项
$query=“从$db\u fb中选择*,其中值='0';
if($result=mysqli_query($connection,$query)){
//对于找到的每个记录
而($row=$result->fetch_array()){
$item_found_count++;//计算找到的所有项目
$t_itemID=$row['itemID'];$t_itemDate=$row['itemDate'];$t_attributeID=$row['attributeID'];//记录此数据,以防我们需要它作为删除记录的“指针”
//echo“找到条目:“.$row['itemID']”.“.$row['itemDate']”;
$query=“从$db\U fb中选择*,其中itemID=$t\U itemID和itemDate<'t\U itemDate'和attributeID='t\U attributeID'和value>'5'按itemDate顺序描述限制1”;
//如果存在此类条目,则必须删除当前条目。
if($SecondResult=mysqli\u查询($connection,$query)){
而($rowSpec=$SecondResult->fetch_array()){
$item_valid_count++;//计算所有实际删除的项目
//echo“
->mark;”打印($rowSpec);echo“
”;
//如果ID、itemDate、attributeID和值一致,则删除
$q_del=“从$db_fb中删除,其中itemID=$t_itemID和itemDate='$t_itemDate'和attributeID='$t_attributeID'和value='0';
$deleteRes=mysqli\u查询($connection,$q\u del);
}
}
//回声“------------------------------------
”;
}
}
//从值相同、attributeID相同、ID相同、itemDates立即连续限制为2的表中选择。删除最近的条目。
$query=“从$db_fb GROUP按项目ID、属性ID、值具有计数(*)的组中选择最大值(项目日期)作为项目日期、项目ID、属性ID、值、计数(*),按项目日期描述的顺序大于1”;
if($ThirdResult=mysqli\u查询($connection,$query)){
而($rowSpec=$ThirdResult->fetch_array()){
$item_duplicates_count++;//计算实际删除的所有项目
$t_itemID=$rowSpec['itemID'];$t_itemDate=$rowSpec['itemDate'];$t_attributeID=$rowSpec['attributeID'];$t_value=$rowSpec['value'];//记录此数据,以防我们需要它作为删除记录的“指针”
//echo“
->mark;”打印($rowSpec);echo“
”;
$q_del=“从$db_fb中删除,其中itemID='$t_itemID'和itemDate='$t_itemDate'和attributeID='$t_attributeID'和value='$t_value';
$deleteRes=mysqli\u查询($connection,$q\u del);
}
}
echo“找到零位:”$找到的物品数量。“
”;
echo“归零,删除有效:”$项目\u有效\u计数。“
”;
回声“剩余归零:”。($item\u found\u count-$item\u valid\u count)。“
”;
回显“连续重复:”$项目重复数;
你能告诉我你的关系(表)中的主键是什么吗?@leoMestizo嗨,我编辑了我的问题,但我在这里也要提到,属性属于itemID key在单独的表中唯一定义的项。是的,但itemID是这个表中的主键?如果是这样,您不尊重候选键的唯一性属性。@leoMestizo itemID不是此表中的主键,因为有多个历史记录与单个项关联,它们都被存储起来,以便在需要时及时保留属性演变的记录。此表没有主键。@leoMestizo您好。此表中不实际需要PK。考虑到也会有很多条目,我决定不包括PK。然而,我编辑了我的问题,并发布了一个包含一点php的解决方案。问题仍然是,如何纯粹用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;