4

所以...

我有一个表(我们称之为数据位置),比如......

Data Location ID    Data ID    Location Type    Location URL   Status    Date
1                   1          Foo              foo/3          Valid     10-21-2014
2                   1          Bar              bar/1          Valid     10-21-2014
3                   1          Foo              foo/2          Valid     03-20-2013
4                   1          Foo              foo/1          Valid     12-01-2010

...等等。该表有许多不同的数据 ID(为简单起见,我没有显示它们)。这个想法是对于给定的数据 ID 和位置类型应该只有 1 个有效条目,正如您在上面看到的,数据 ID 1 的所有 Foo 位置都是有效的(foo/1、foo/2、foo/3) .

有人可以帮我构建一个查询以将所有重复记录(相同的数据 ID 和位置类型)状态列更新为无效,除了最新的条目。我有一个查询可以识别符合重复条件的行,但我不确定如何将 group by 与 max(或不是 max?)结合起来并更新。似乎分区可能是一种方式,但我对查询有点生疏,所以我很感激任何帮助。所以对于上面的数据,我希望结果是......

Data Location ID    Data ID    Location Type    Location URL   Status    Date
1                   1          Foo              foo/3          Valid     10-21-2014
2                   1          Bar              bar/1          Valid     10-21-2014
3                   1          Foo              foo/2          Invalid   03-20-2013
4                   1          Foo              foo/1          Invalid   12-01-2010

...提前致谢!

4

3 回答 3

2

您可以使用一个 UPDATE 语句:

UPDATE Data_Location u
INNER JOIN (
  SELECT `Data ID`, `Location Type`, MAX(`Date`) AS max_date
  FROM Data_Location
  GROUP BY `Data ID`, `Location Type`
) t ON u.`Data ID` = t.`Data ID` 
   AND u.`Location Type` = t.`Location Type`
SET u.Status = 'Invalid'
WHERE u.`Date` <> t.max_date

在SQL Fiddle上进行测试

于 2014-10-21T20:22:40.877 回答
1
DROP TABLE IF EXISTS my_table;

CREATE TABLE my_table
(ID    INT NOT NULL AUTO_INCREMENT PRIMARY KEY
,Data_ID INT  NOT NULL
,Location_Type    VARCHAR(5) NOT NULL
,Status    VARCHAR(12) NOT NULL
);

INSERT INTO my_table VALUES
(1,1,'Foo','Valid'),
(2,1,'Bar','Valid'),
(3,1,'Foo','Valid'),
(4,1,'Foo','Valid');     

SELECT * FROM my_table;
+----+---------+---------------+--------+
| ID | Data_ID | Location_Type | Status |
+----+---------+---------------+--------+
|  1 |       1 | Foo           | Valid  |
|  2 |       1 | Bar           | Valid  |
|  3 |       1 | Foo           | Valid  |
|  4 |       1 | Foo           | Valid  |
+----+---------+---------------+--------+

UPDATE my_table x 
  JOIN my_table y 
    ON y.data_id = x.data_id 
   AND y.location_type = x.location_type 
   AND y.id < x.id 
   SET x.status = 'Invalid';

SELECT * FROM my_table;
+----+---------+---------------+---------+
| ID | Data_ID | Location_Type | Status  |
+----+---------+---------------+---------+
|  1 |       1 | Foo           | Valid   |
|  2 |       1 | Bar           | Valid   |
|  3 |       1 | Foo           | Invalid |
|  4 |       1 | Foo           | Invalid |
+----+---------+---------------+---------+


mysql>
于 2014-10-21T20:56:40.227 回答
0
  • 使用一个简单的查询(如UPDATE table SET status = 'invalid'.
  • 然后执行另一个查询,按数据 ID 和位置类型对行进行分组,并按 ID 降序排列。将选定的行设置为有效。我不确定我在下面提供的两个查询是否可以合并,并且我现在没有要测试的环境,但它可以这样工作:

-

$query = $yourPDO->prepare('SELECT id FROM table ORDER BY id DESC GROUP BY data_id, location_type');
$query->execute();
$results = $query->fetchAll(PDO::FETCH_OBJ);

$ids = [];

// not sure if there is an array_* function for this functionality:
foreach ($results as $row)
{
    $ids[] = $row->id;
}

$yourPDO->prepare('UPDATE table SET status = "valid" WHERE id IN (' . implode(', ', $ids) . ')');
于 2014-10-21T20:03:45.857 回答