Mysql 将右表上的多条记录过滤为左表的1条记录
所以我有一个翻译表,它保存了一个地名的各种表示形式。我在Mysql 将右表上的多条记录过滤为左表的1条记录,mysql,join,Mysql,Join,所以我有一个翻译表,它保存了一个地名的各种表示形式。我在placeId上加入这个表,这个表作为右侧(左侧包含位置的信息) 然而,在placeId上连接可能会产生更多的翻译,见下表。preferredName/shortName/historicName的内容都是0或1。但是,没有规则规定每个翻译至少应该有一条preferredName=1的记录 因此,我的结论是:我如何才能只选择这些翻译中的一种,特别是: 如果存在带有preferredName=1的记录:使用此 否则,如果记录存在且short
placeId
上加入这个表,这个表作为右侧(左侧包含位置的信息)
然而,在placeId上连接可能会产生更多的翻译,见下表。preferredName/shortName/historicName的内容都是0或1。但是,没有规则规定每个翻译至少应该有一条preferredName=1
的记录
因此,我的结论是:我如何才能只选择这些翻译中的一种,特别是:
- 如果存在带有
preferredName=1的记录:使用此
- 否则,如果记录存在且
shortName=1
:使用此
- 否则,如果两者都不为真(因此都为0),则选择该记录
有线索吗?它基本上归结为将右表中的多个匹配项过滤到左表中的一条记录。您可以在不同的条件下加入3次,并合并结果:
select
a.*,
coalesce(name1.alternateName, name2.alternateName, name3.alternateName) as alternateName
from _table1_ as a
left join _table2_ as name1 on (a.placeId = name1.placeId and name1.preferredName=1)
left join _table2_ as name2 on (a.placeId = name2.placeId and name2.shortName=1)
left join _table2_ as name3 on (a.placeId = name3.placeId and name3.preferredName=0 and name3.shortName=0)
group by a.placeId
您可以在不同条件下加入3次,并合并结果:
select
a.*,
coalesce(name1.alternateName, name2.alternateName, name3.alternateName) as alternateName
from _table1_ as a
left join _table2_ as name1 on (a.placeId = name1.placeId and name1.preferredName=1)
left join _table2_ as name2 on (a.placeId = name2.placeId and name2.shortName=1)
left join _table2_ as name3 on (a.placeId = name3.placeId and name3.preferredName=0 and name3.shortName=0)
group by a.placeId
根据我之前的评论,您可以在子请求上提出加入请求
试试这个:
SELECT * FROM mytable WHERE placeId = 554 ORDER BY preferredName DESC, shortName DESC;
它会根据您的喜好,完全按照您的意愿排序结果。只需增加一个限制1蚂蚁你是对的
SELECT * FROM mytable WHERE placeId = 554 ORDER BY preferredName DESC, shortName DESC LIMIT 1;
所以,只需添加请求的第一部分,并在此基础上加入;)
编辑:以下内容与注释相关
LEFT OUTER JOIN
(SELECT * FROM alternatename
WHERE isoLanguage="NL" AND geonameid = a1.geonameid
ORDER BY isPreferredName DESC, isShortName DESC
LIMIT 1
)
AS alternate10
ON
alternate10.geonameid = a1.geonameid
根据我之前的评论,您可以在子请求上提出加入请求
试试这个:
SELECT * FROM mytable WHERE placeId = 554 ORDER BY preferredName DESC, shortName DESC;
它会根据您的喜好,完全按照您的意愿排序结果。只需增加一个限制1蚂蚁你是对的
SELECT * FROM mytable WHERE placeId = 554 ORDER BY preferredName DESC, shortName DESC LIMIT 1;
所以,只需添加请求的第一部分,并在此基础上加入;)
编辑:以下内容与注释相关
LEFT OUTER JOIN
(SELECT * FROM alternatename
WHERE isoLanguage="NL" AND geonameid = a1.geonameid
ORDER BY isPreferredName DESC, isShortName DESC
LIMIT 1
)
AS alternate10
ON
alternate10.geonameid = a1.geonameid
按“preferredName”和“ShortName”排序,然后选择第一个结果;)当您将10个位置与这些翻译匹配时,您将如何做到这一点;在这种情况下,我想返回10条记录(每条记录都有适当的翻译作为一个字段),您可以根据子请求“选择…”加入。。。从…起order by…'和limit 1'我只需添加一个答案,向您显示您需要加入的请求;)按“preferredName”和“ShortName”排序,然后选择第一个结果;)当您将10个位置与这些翻译匹配时,您将如何做到这一点;在这种情况下,我想返回10条记录(每条记录都有适当的翻译作为一个字段),您可以根据子请求“选择…”加入。。。从…起order by…'和limit 1'我只需添加一个答案,向您显示您需要加入的请求;)嗯,是的,这似乎解决了问题;然而:我使用了一个相当大的数据集,我刚刚将这个子查询构建到我的主查询中,它增加了13秒的执行时间。如果您希望我们尝试优化您的请求,您可以向我们展示您的主请求吗?这个请求很快,所以我认为我们需要在你的main上工作,也许找到wich索引在你的情况下是有用的。这是总的想法。注意:全文搜索(匹配/反对)不是罪魁祸首。当不执行子查询时,查询的执行时间大约为50ms。我看到了两种可能的改进方法:1=>在子请求的wehre中添加g.geonameid条件。因此,order by将处理非常少量的数据。(与a1或a2相同)“其中isoLanguage=“NL”和geonameid=g.geonameid”我想我将使用连接解决方案;我对子查询做了一些修改,但mysql似乎没有对它们进行足够的优化。遗憾的是,我使用的数据集并不是最抽象的数据集,因此我无法避免三次加入同一个表。3在这种情况下,子查询将影响性能mm是的,这似乎解决了问题;然而:我使用了一个相当大的数据集,我刚刚将这个子查询构建到我的主查询中,它增加了13秒的执行时间。如果您希望我们尝试优化您的请求,您可以向我们展示您的主请求吗?这个请求很快,所以我认为我们需要在你的main上工作,也许找到wich索引在你的情况下是有用的。这是总的想法。注意:全文搜索(匹配/反对)不是罪魁祸首。当不执行子查询时,查询的执行时间大约为50ms。我看到了两种可能的改进方法:1=>在子请求的wehre中添加g.geonameid条件。因此,order by将处理非常少量的数据。(与a1或a2相同)“其中isoLanguage=“NL”和geonameid=g.geonameid”我想我将使用连接解决方案;我对子查询做了一些修改,但mysql似乎没有对它们进行足够的优化。遗憾的是,我使用的数据集并不是最抽象的数据集,因此我无法避免三次加入同一个表。3在这种情况下,子查询将影响性能我将立即尝试此方法;只有一件事:对于preferredName/shortName,1-1、1-0、0-1和0-0对都可以存在(对甚至可以存在两个,但我们可以任意取一个)。所以它应该在1-0之前返回1-1,在0-1之前返回1-0,在0-0之前返回0-1。我将在稍后进行尝试;只有一件事:对于preferredName/shortName,1-1、1-0、0-1和0-0对都可以存在(对甚至可以存在两个,但我们可以任意取一个)。所以它应该在1-0之前返回1-1,在0-1之前返回1-0,在0-0之前返回0-1