【问题标题】:Joined query missing records加入查询缺失记录
【发布时间】:2019-09-11 06:38:34
【问题描述】:

我有一个数据库,其中包含一个人员表和另一个包含这些人姓名的表。对于每个人,姓名表中至少有一条记录,其中一条记录被设置为该人的“person_default_name_id”,但该名称在不同语言中的其他变体。这个想法是,查找表格的用户将有一个首选语言集(例如英语、西班牙语、俄语)和一个首选脚本集,该脚本集基于他们的首选语言(例如,如果他们的首选语言是英语或西班牙语,则脚本将是“拉丁语”,而如果首选语言是俄语,则脚本将是“西里尔语”)。这有点复杂,我想显示一个名称列表,但每个人只显示一个名称,并且应该根据用户选择的语言和脚本最适合的方式显示一个选择的名称。

下面的代码是我正在尝试的:

SELECT 
    people.person_id,
    names.name
FROM 
    `people` 
LEFT JOIN
    `names` ON names.person_id=people.person_id
LEFT JOIN
    `languages` ON names.language_id = languages.language_id
LEFT JOIN
    `language_scripts` ON languages.language_id = language_scripts.language_id
WHERE 
    (
    /* 1st preference - display the default name for the person IF the default name's language writing system matches the user's writing system */
    (people.person_default_name_id=names.name_id AND language_scripts.script_id = :user_script_id)
    OR
    /* 2nd preference - display the alternative name in the user's chosen language if an alternative name exists in that language */
    names.language_id = :user_language_id
    OR
    /* 3rd preference - display the alternative name in the user's chosen writing system if an alternative name exists in that writing system */
    language_scripts.script_id = :user_script_id
    )
GROUP BY 
    people.person_id 
ORDER BY 
    names.name ASC

示例数据如下:

表格:人

 person_id | person_default_name_id
------------------------------------
 1         | 2

表格:名称

 name_id | name   | person_id | language_id
--------------------------------------------
 1       | George | 1         | 1
 2       | Jorge  | 1         | 2
 3       | Джордж | 1         | 3

表格:语言

 language_id | language
------------------------
 1           | English
 2           | Spanish
 3           | Russian

表:语言脚本

 language_script_id | language_id | script_id
----------------------------------------------
 1                  | 1           | 1
 2                  | 2           | 1
 3                  | 3           | 2

表格:脚本

 script_id | script
----------------------
 1         | Latin
 2         | Cyrillic

我发现一些预期的记录没有通过。我猜我可以对我的查询进行改进,但我的技能还不够先进,无法知道最佳路径。谁能看到我做错了什么?

【问题讨论】:

  • 请检查您的加入姓名表,姓名表中没有 person_id。据我了解,它应该是 name_id。你的要求有点条件。就像你想要的那样......做这个......否则做这个......通常我用PHP(任何编程语言)而不是数据库(特别是mysql)来做这种类型的解决方案.
  • usually i do this type of solution in PHP 使用 PHP 实现大量 if else 速度非常慢,我建议坚持使用问题中使用的 SQL
  • 嗨@dollas,您的SQL 缺少某些内容,这是缺少names.software_title_language_id,您可以在列中重新添加吗?
  • @MohitSaini 感谢您指出遗漏。我确实在实际表中有 names.person_id 但忘了将其复制到我的问题中。
  • @NgSekLong 感谢您的回复。 names.software_title_language_id 是我在输入这个问题时犯的一个错误(我同时在做两件事!)。实际查询中是names.language_id

标签: mysql


【解决方案1】:

我建议您将 where 子句条件放在您的 select 语句中,并为每条记录返回一个“分数”。将其从 where 子句中完全删除,如果返回 0 分,它可能会让您了解为什么缺少记录。

case when condition Then 5 当条件然后 4 ETC... 否则 0 结束案例

对结果进行评分后,您可以按分数降序排列,然后每人拿第一个。或者添加额外的外部查询以仅返回每人得分最高的行。

很抱歉用我的手机接听电话。

【讨论】:

  • 感谢您的建议。使用案例和外部查询对我来说是新的。你会碰巧知道一些我可以看的很好的例子来证明你的建议吗?
  • 在此基础上,我提出了一个新问题,因为我现在在外部查询建议方面遇到了困难,并认为最好单独发布。新问题可见stackoverflow.com/questions/59185690/…
  • dallas1,既然您根据我的建议提出了一个新问题,请给我一个可靠的答案并为我的答案投票!
  • 已完成,但由于我的声誉得分低于 15,因此不会公开显示。
猜你喜欢
  • 2021-05-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-15
  • 2017-05-05
  • 2021-01-17
  • 2014-09-21
相关资源
最近更新 更多