【问题标题】:SQL - JOIN on a preferable value otherwise on a default oneSQL - 加入一个更可取的值,否则加入一个默认值
【发布时间】:2021-02-27 00:06:49
【问题描述】:

我有两张桌子:

  • 关注列表
media_id saved_language
000001 en
000002 en
  • 媒体
media_id media_title data_language
000001 Title in English en
000002 Title in English en
000002 Title in Italian it

我想加入这两个 media_id 相同但语言必须是我输入的常量(例如“it”)的表(如果可用),否则它应该使用保存在监视列表表中的默认语言永远在场。

我写的查询是这样的:

SELECT * FROM watchlist
LEFT JOIN media 
   ON media.media_id = watchlist.media_id 
   AND (media.data_language = "it" OR media.data_language = watchlist.saved_language)

但是使用一个简单的 OR 我显然得到了两种语言的结果。我也已经尝试过使用 CASE,但结果相同。我想要的是为每个 media_id 保留一行,其中语言最好是“它”,或者,只有当它在媒体表中不可用时,才使用保存在监视列表中的那个,它总是有匹配的。

我想要的结果示例:

media_id media_title saved_language data_language
000001 Title in English en en
000002 Title in Italian en it

【问题讨论】:

  • 用您正在使用的数据库标记您的问题。

标签: mysql sql join


【解决方案1】:

你可以使用窗口函数:

SELECT w.*
FROM (SELECT wl.*, m.*,
             ROW_NUMBER() OVER (PARTITION BY wl.media_id
                                ORDER BY (CASE m.data_language WHEN 'it' THEN 1 ELSE 2 END)
                               ) as seqnum
      FROM watchlist wl LEFT JOIN
           media m
           ON m.media_id = wl.media_id AND
              m.data_language IN ('it', wl.saved_language)
     ) w
WHERE seqnum = 1;

但是,如果您只想要标题,那么两个连接似乎更简单:

select wl.*, coalesce(m_it.title, m_saved.title) as title
from watchlist wl left join
     media m_it
     on m_it.media_id = wl.media_id and
        m_it.language = 'it' left join
     media m_saved
     on m_saved.media_id = wl.media_id and
        m_saved.langauge = wl.saved_language;

【讨论】:

  • Windows 函数是一个不错的选择,如果可用的话。row_number 和分区是我认为的 oracle 唯一的风格。
  • @JensKrogsboell 。 . .一点也不。我认为,窗口函数已经成为 SQL 标准的一部分大约 2 年了。
  • 好的——很好。那么我推荐你的答案:)
【解决方案2】:

我会试试的

SELECT *
FROM media m
WHERE m.data_language = ‘it’
UNION
SELECT *
FROM media m
JOIN watchlist w ON w.media_id = m.media_id
AND w.saved_language = m.data_language
WHERE m.media_id NOT IN (
    SELECT m2.media_id
    FROM media m2
    WHERE m2.data_language = ‘it’
  )

【讨论】:

    猜你喜欢
    • 2016-04-24
    • 2021-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多