我有一长串名称,其格式如下。一个人在表中可能会用几种不同的方式表示自己的名字(例如,“史密斯,汤姆”和“汤姆·史密斯”)。
查询将通过类似搜索(例如"SELECT * FROM table WHERE person_name LIKE "%smith%"
)进行。
如果某人的布尔字段is_display
被选中为真,那么我只希望将is_display
设置为true的行,如果此人的ID未被选中is_display
,我然后想回到is_preferred
字段上。
因此,理想情况下,搜索“史密斯”只会返回第1行和第4行。
ID person_id person_name is_preferred is_display
1 123456 Tom Smith 0 1
2 223456 Madonna 1 1
3 123456 Smith, Tom 1 0
4 423456 Smith, Frank 1 0
5 423456 Smith, Frank R. 0 0
我已经研究过SQL if / else和CASE语句,但是还没有找到满足此需求的命令。
最接近我的是:
SELECT *
FROM artist_aliases
WHERE ( (alias LIKE '%smith%' AND display=1) OR
(alias LIKE '%smith%' AND preferred=1) )
然后,我在SQL之后的代码中对结果进行按摩。但是我想有一种更优雅的方法可以仅在SQL中执行此操作。
答案 0 :(得分:2)
您似乎希望按人员优先排序。
在MySQL 8+中,这看起来像:
select aa.*
from (select aa.*,
row_number() over (partition by person_id order by display desc, preferred desc) as seqnum
from artist_aliases aa
where alias like '%smith%'
) aa
where seqnum = 1;
在早期版本中,您可以使用相关子查询:
select aa.*
from artist_aliases aa
where aa.alias like '%smith%' and
aa.id = (select aa2.id
from artist_aliases aa2
where aa2.alias like '%smith%' and
aa2.person_id = aa.person_id
order by aa2.display desc, aa2.preferred desc
limit 1
);