简体   繁体   English

在WHEN子句中具有多个条件的MySQL CASE

[英]MySQL CASE with multiple conditions in WHEN clause

There are tracks and albums in my database. 我的数据库中有曲目和专辑。 Each track can pertain to an album. 每个曲目都可以属于一个专辑。 The users can update which tracks pertain to an album. 用户可以更新与专辑有关的曲目。

PHP receives an array of track ID's, and an album ID. PHP接收一个曲目ID数组和一个专辑ID。 I am trying to create 1 query which will update a track's album ID, and at the same time NULL a track's album ID if it doesn't pertain to the album anymore. 我正在尝试创建1个查询,该查询将更新曲目的专辑ID,如果不再与专辑相关,则同时将曲目的专辑ID设为NULL。

$query = "UPDATE tracks
          SET album_id =
            CASE
              WHEN album_id = :album_id AND NOT FIND_IN_SET(tempkey, :tracks) THEN NULL
              WHEN FIND_IN_SET(tempkey, :tracks) THEN :album_id
            END
          WHERE account_id = :account_id";

$statement = $pdo_conn->prepare($query);
$statement->execute($data);

The part album_id = :album_id doesn't seem to be working. album_id = :album_id部分似乎album_id = :album_id Each time I update the album ID of any given tracks, it NULLs the album ID of all other tracks. 每次更新任何给定曲目的专辑ID时,它都会使所有其他曲目的专辑ID为NULL。

How could I fix this query to achieve what I want (if it's still worth it compared to just using 2 queries)? 我该如何解决该查询以实现所需的功能(如果与仅使用2个查询相比还是值得的话)?

Ps: Using FIND_IN_SET which is like NOT IN / IN but without the hassle / dirtiness which PDO poses when using that. FIND_IN_SET :使用FIND_IN_SET就像NOT IN / IN但是没有使用时PDO造成的麻烦/肮脏。

You need ELSE condition. 您需要ELSE条件。 Otherwise you get ELSE NULL by default 否则默认为ELSE NULL

CASE
  WHEN album_id = :album_id AND NOT FIND_IN_SET(tempkey, :tracks) THEN NULL
  WHEN FIND_IN_SET(tempkey, :tracks) THEN :album_id
  ELSE album_id
END

Another approach is to do some filtering in the WHERE . 另一种方法是在WHERE进行一些过滤。 Your query attempts to update all rows for an account_id . 您的查询尝试更新account_id所有行。 That might or might not be a good thing. 那可能不是好事。

Here is one way to move some filtering to the WHERE : 这是将一些过滤移到WHERE一种方法:

UPDATE tracks
    SET album_id = (CASE WHEN FIND_IN_SET(tempkey, :tracks) > 0 THEN :album_id END)
    WHERE account_id = :account_id AND
          (album_id = :album_id OR FIND_IN_SET(tempkey, :tracks));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM