【问题标题】:MYSQL join condition match only one row based on priority [closed]MYSQL连接条件根据优先级仅匹配一行[关闭]
【发布时间】:2021-04-26 19:02:49
【问题描述】:

我有一些用英语和波斯语 (fa) 写的帖子,所以我的目的是获取每个英语帖子的所有 fa 翻译帖子,如果不存在则获取英语默认帖子。

wp_posts 表 897,899,902,1034 are English Posts 1019,1035 are Persian Posts 1019 is translated post of 902 and 1035 is translated post of 1034

这些属性在另一个名为 wp_icl_translations 的表中定义

element_id指的是wp_posts.ID,post和翻译版本都是同一个trid,source_language_code of null表示英文原帖,如果设置为'en'则表示是en语言的翻译帖。


所以我想要的结果是:

我已经可以做到这一点了:

如果存在,我需要一些条件来选择仅 fa,如果不存在,则选择默认 (en)。

这是所有示例数据和所有内容的完整小提琴链接:

https://dbfiddle.uk/?rdbms=mysql_5.6&fiddle=c86dce6ea0b87f863782fbff47e0e526

选择所有列对我来说非常重要,因为这只是一个测试表,真正的表还有很多列,我需要将它们全部获取。

以下是完整的表格,以一行为例:

https://dbfiddle.uk/?rdbms=mysql_5.6&fiddle=37f8af9fd14c60f4ea23fd4778b86806

【问题讨论】:

  • 我不明白你的表结构。在我看来,应该有第三个表,其中包含语言代码、帖子 ID 和翻译。这些数据存储在哪里?
  • @TimBiegeleisen 你介意检查小提琴链接吗?我认为它会更明显。没有其他表。wp_posts 有原始帖子,翻译后的帖子都在 wp_posts 中。但是 wp_icl_translations 可以显示哪个是原创的,哪个是翻译的,并且关系依赖于 trid 列,因此所有翻译和原始帖子都具有相同的 trid 值。
  • 请不要delete & repost,编辑。在您第一次发帖时,这有我的 cmets 的所有问题。 PS请use text, not images/links, for text--including tables & ERDs。只提供您需要的东西并将其与您的问题联系起来。仅将图像用于无法表达为文本或增强文本的内容。在图像中包含图例/键和说明。 PS 但这是给出minimal reproducible example 的结果。 PS请通过编辑进行澄清,而不是cmets。 PS 将所有需要询问的内容放在您的帖子中,而不仅仅是在链接中。
  • 请在代码问题中给出minimal reproducible example--cut & paste & runnable code,包括最小的代表性示例输入为代码;期望和实际输出(包括逐字错误消息);标签和版本;明确的规范和解释。给出您可以给出的最少代码,即您显示的代码可以通过您显示的代码扩展为不正常。 (调试基础。)对于包含 DBMS 和 DDL(包括约束和索引)和输入为格式化为表的代码的 SQL。 How to Ask help center 停止尝试编写您的总体目标并从给定的代码中解释您的期望以及原因。
  • 感谢您的所有解释,下次我会问问题时会使用它。

标签: mysql join conditional-statements


【解决方案1】:
SELECT COALESCE(p2.id, p1.id) id, COALESCE(p2.post_title, p1.post_title) post_title
FROM wp_icl_translations t1
JOIN wp_posts p1 ON t1.element_id = p1.id
LEFT JOIN wp_icl_translations t2 ON t1.trid = t2.trid AND t2.language_code = 'fa'
LEFT JOIN wp_posts p2 ON t2.element_id = p2.id
WHERE t1.language_code = 'en'
ORDER BY id

fiddle


我想以某种方式使用 * 来获取所有真正重要的列 .. 两个表都在这里完成创建:https://dbfiddle.uk/?rdbms=mysql_5.6&fiddle=37f8af9fd14c60f4ea23fd4778b86806 – steve moretz

如果您需要完整的列,则必须再添加一个表副本并从中提取整行。此类连接所需的主键:

SELECT p0.*, t0.*
FROM wp_icl_translations t1
JOIN wp_posts p1 ON t1.element_id = p1.id
LEFT JOIN wp_icl_translations t2 ON t1.trid = t2.trid AND t2.language_code = 'fa'
LEFT JOIN wp_posts p2 ON t2.element_id = p2.id
JOIN wp_icl_translations t0 ON t0.translation_id = COALESCE(t2.translation_id, t1.translation_id)
JOIN wp_posts p0 ON p0.id = COALESCE(p2.id, p1.id)
WHERE t1.language_code = 'en'
ORDER BY id

fiddle

【讨论】:

  • 感谢您的回答,令人惊讶的只有一个问题我在这个小提琴中简化了 wp_posts 表,示例它有更多的列,所以我想以某种方式使用 * 来获取所有真正重要的列
  • 我还添加了我的解决方案,使用 sea eff 建议的 group 做同样的事情,但我无法选择所有带有 * 的列。请检查我编辑的问题的结尾并添加了这些信息
  • @stevemoretz 我想以某种方式使用 * 来获取所有真正重要的列 将两个表的完整 CREATE TABLE 添加到您的问题中(作为格式化文本)。指定您需要检索的完整列列表。
  • 问题是它们可能会因不同的因素而有所不同翻译和各种翻译不同的表但相同的 element_id 可靠性但列不同。
  • 如果我可以选择整行及其所有列,那将是完美的。这不可能吗?
猜你喜欢
  • 2019-12-01
  • 2011-01-31
  • 1970-01-01
  • 1970-01-01
  • 2010-09-28
  • 2017-05-01
  • 2015-08-23
  • 2010-10-03
  • 1970-01-01
相关资源
最近更新 更多