如何更新SELECT语句的结果?

时间:2016-05-26 18:50:12

标签: php mysql sql pdo

我有一张这样的表:

// notifications
+----+--------------+------+---------+------------+
| id |      event   | seen | id_user | time_stamp |
+----+--------------+------+---------+------------+
| 1  | vote         | 1    | 123     | 1464174617 |
| 2  | comment      | 1    | 456     | 1464174664 |
| 3  | vote         | 1    | 123     | 1464174725 |
| 4  | answer       | 1    | 123     | 1464174813 |
| 5  | comment      | NULL | 456     | 1464174928 |
| 6  | comment      | 1    | 123     | 1464175114 |
| 7  | vote         | NULL | 456     | 1464175317 |
| 8  | answer       | NULL | 123     | 1464175279 |
| 9  | vote         | NULL | 123     | 1464176618 |
+----+--------------+------+---------+------------+ 

这是我的疑问:

(SELECT id, event, seen, time_stamp 
 FROM notifications n
 WHERE id_user = :id AND seen IS NULL
)UNION
(SELECT id, event, seen, time_stamp
 FROM notification n
 WHERE id_user = :id AND seen IS NOT NULL
 LIMIT 2
)UNION 
(SELECT id, event, seen, time_stamp 
 FROM notifications n
 WHERE id_user = :id 
 ORDER BY (seen IS NULL) desc, time_stamp desc
 LIMIT 15
)
ORDER BY (seen IS NULL) desc, time_stamp desc;

现在我尝试从上面的查询更新匹配的行并设置seen = 1,如下所示:

UPDATE notifications SET seen = 1 WHERE /* the result of query above */

我该怎么做?

注意:我还使用PHP和PDO来执行SELECT查询(如果知道这一点很重要)

$stm = $db->prepare(" (SELECT id, ... ");
$stm->execute( /* passing some variables */);
$stm->fetchAll(PDO::FETCH_ASSOC);

5 个答案:

答案 0 :(得分:1)

我认为你可以在where子句中使用..但在这种情况下你需要ond id

    UPDATE notifications SET seen = 1 WHERE id in (
    (SELECT id
     FROM notifications n
     WHERE id_user = :id AND seen IS NULL
    )UNION
    (SELECT id
     FROM notification n
     WHERE id_user = :id AND seen IS NOT NULL
     LIMIT 2
    )UNION 
    (SELECT id
     FROM notifications n
     WHERE id_user = :id 
     ORDER BY (seen IS NULL) desc, time_stamp desc
     LIMIT 15
    ))

答案 1 :(得分:1)

如果您想在MySQL中执行此操作,请使用JOIN

update notifications n join
       (select id
        from ((SELECT id, event, seen, time_stamp 
               FROM notifications n
               WHERE id_user = :id AND seen IS NULL
              ) UNION
              (SELECT id, event, seen, time_stamp
               FROM notification n
               WHERE id_user = :id AND seen IS NOT NULL
               LIMIT 2
              ) UNION 
              (SELECT id, event, seen, time_stamp 
               FROM notifications n
               WHERE id_user = :id 
               ORDER BY (seen IS NULL) desc, time_stamp desc
               LIMIT 15
              )) n
       ) nids
       on n.id = nids.id
    set seen = 1;

答案 2 :(得分:1)

seen只能是1null。在这种情况下,您从UNION查询获得的大部分内容都是无关紧要的。在我看来,您尝试做的更新的最终结果将是:

UPDATE notifications SET seen = 1 WHERE id_user = :id AND seen IS NULL

其他任何内容都会更新已经11的内容。

答案 3 :(得分:0)

您可以稍微修改您的查询以用作update语句的子查询:

UPDATE notifications SET seen = 1 WHERE id in (
    (SELECT id
     FROM notifications n
     WHERE id_user = :id AND seen IS NULL
    )UNION
    (SELECT id
     FROM notification n
     WHERE id_user = :id AND seen IS NOT NULL
     LIMIT 2
    )UNION 
    (SELECT id
     FROM notifications n
     WHERE id_user = :id 
     ORDER BY (seen IS NULL) desc, time_stamp desc
     LIMIT 15
    )
)

答案 4 :(得分:0)

我假设您已将所有适用的ID检索到您的应用程序中。你需要做的就是

UPDATE notifications
SET seen = 1
WHERE id IN (?,?,?)

其中?被id值替换。