Dan P.
Dan P.

Reputation: 1775

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. 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.

$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. Each time I update the album ID of any given tracks, it NULLs the album ID of all other tracks.

How could I fix this query to achieve what I want (if it's still worth it compared to just using 2 queries)?

Ps: Using FIND_IN_SET which is like NOT IN / IN but without the hassle / dirtiness which PDO poses when using that.

Upvotes: 2

Views: 4070

Answers (2)

Gordon Linoff
Gordon Linoff

Reputation: 1270463

Another approach is to do some filtering in the WHERE. Your query attempts to update all rows for an account_id. That might or might not be a good thing.

Here is one way to move some filtering to the 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));

Upvotes: 0

Juan Carlos Oropeza
Juan Carlos Oropeza

Reputation: 48197

You need ELSE condition. Otherwise you get ELSE NULL by default

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

Upvotes: 3

Related Questions