Aqui está uma maneira típica de fazer essa consulta sem usar o método de subconsulta que você mostrou. Isso pode satisfazer o pedido de @Godeke para ver uma solução baseada em junção.
SELECT *
FROM movies m
LEFT OUTER JOIN seen s
ON (m.id = s.movie_id AND s.user_id = 123)
WHERE s.movie_id IS NULL;
No entanto, na maioria das marcas de banco de dados, essa solução pode ter um desempenho pior do que a solução de subconsulta. É melhor usar EXPLAIN para analisar ambas as consultas, para ver qual delas se sairá melhor de acordo com seu esquema e dados.
Aqui está outra variação da solução de subconsulta:
SELECT *
FROM movies m
WHERE NOT EXISTS (SELECT * FROM seen s
WHERE s.movie_id = m.id
AND s.user_id=123);
Esta é uma subconsulta correlacionada, que deve ser avaliada para cada linha da consulta externa. Normalmente, isso é caro e sua consulta de exemplo original é melhor. Por outro lado, no MySQL "
NOT EXISTS
" geralmente é melhor que "column NOT IN (...)
" Novamente, você deve testar cada solução e comparar os resultados para ter certeza. É uma perda de tempo escolher qualquer solução sem medir o desempenho.