我有这个SQL查询:
SELECT v.*, group_concat(distinct(vi.interest_id)) as interests, group_concat(distinct(vs.skill_id)) as skills, vc.date_from
FROM `vacancies` as v
LEFT JOIN `vacancy_interests` as vi on v.vacancy_id = vi.vacancy_id
LEFT JOIN `vacancy_skills` as vs on v.vacancy_id = vs.vacancy_id
LEFT JOIN `vacancy_calendar` as vc on v.vacancy_id = vc.vacancy_id
WHERE v.vacancy_visibility_end_date >= CURDATE()
GROUP BY v.vacancy_id
考虑此查询返回以下结果(最后3列是此问题中讨论的那些):
vacancy_id,org_id,name,description,number_required,occupancy_kind,website,offer,logo,banner,address_country,address_city,address_postal_code,address_line_1,address_line_2,vacancy_visibility_start_date,vacancy_visibility_end_date,engagement,interests,skills,date_from
"2","1","test123","aze<sdgqswdfg","1","1","","blabla",NULL,"12049394_10208129537615226_4853636504350654671_n.jpg","Belgie","Brussel","1000","Brusselsestraat 15",NULL,"2016-09-02 00:00:00","2016-09-19 00:00:00","3","13,6,1","4,3","2016-09-13 00:00:00"
"3","1","blablabla","lkpjoip","1","2","","blabla",NULL,NULL,"Belgie","Antwerpen","2000","Antwerpsestraat 16",NULL,"2016-09-02 00:00:00","2016-09-29 00:00:00","3","28","7,8,5","2016-09-01 00:00:00"
"4","1","hahaha","14556dsf","1","3","","blabla",NULL,NULL,"Belgie","Mechelen","2800","Mechelsesteenweg 17",NULL,"2016-09-02 00:00:00","2016-09-28 00:00:00","3",NULL,NULL,"2016-09-26 00:00:00"
"5","1","omggg","45sdfdj5","1","1","","blabla",NULL,NULL,"Belgie","Gent","3000","Gentsesteenweg 18",NULL,"2016-09-02 00:00:00","2016-09-30 00:00:00","3","17,11","4,1","2016-09-19 00:00:00"
"6","1","this is a test","wauhiufdsq","1","2","","blabla",NULL,NULL,"Belgie","Luik","4000","Luikseweg 19",NULL,"2016-09-02 00:00:00","2016-09-30 00:00:00","3","19,17,22","6","2016-08-10 00:00:00"
请注意,空缺利息和空缺技能表可以包含单个空缺的多个记录。例如。可能是空缺3有3行,所有不同的interest_id。 group_concat在这里解决了我的问题。 所以这个查询工作得很好。
但是,我遇到的两个问题如下:
1)当我通过ID在HAVING中添加一个过滤器时,这只会返回一行而不是预期的两行。
SELECT v.*, group_concat(distinct(vi.interest_id)) as interests, group_concat(distinct(vs.skill_id)) as skills, vc.date_from
FROM `vacancies` as v
LEFT JOIN `vacancy_interests` as vi on v.vacancy_id = vi.vacancy_id
LEFT JOIN `vacancy_skills` as vs on v.vacancy_id = vs.vacancy_id
LEFT JOIN `vacancy_calendar` as vc on v.vacancy_id = vc.vacancy_id
WHERE v.vacancy_visibility_end_date >= CURDATE()
GROUP BY v.vacancy_id
HAVING interests IN (17)
这只返回一行。即使用vacanacy_id 5进行记录,同时显然也应返回vacancy_id = 6。
对我来说最奇怪的是,如果我做同样的事情,但是对于技能(HAVING技能IN(4)),这确实会返回多行,并且结果正确。
2)当我想过滤date_from时(连同HAVING中的兴趣和技能,我会做以下事情:
SELECT v.*, group_concat(distinct(vi.interest_id)) as interests, group_concat(distinct(vs.skill_id)) as skills, vc.date_from
FROM `vacancies` as v
LEFT JOIN `vacancy_interests` as vi on v.vacancy_id = vi.vacancy_id
LEFT JOIN `vacancy_skills` as vs on v.vacancy_id = vs.vacancy_id
LEFT JOIN `vacancy_calendar` as vc on v.vacancy_id = vc.vacancy_id
WHERE v.vacancy_visibility_end_date >= CURDATE() AND date(vc.date_from) > '2016-09-10'
GROUP BY v.vacancy_id
HAVING skills IN (4)
这只会让我回到空缺数字5,显然空缺数字2的日期大于2016-09-10(2016-09-13 00:00:00)....
我在这里做错了什么?
答案 0 :(得分:1)
您的HAVING
条款是检查条件是否存在的错误方法。不要使用连接值,只需使用:
HAVING MAX(vi.interest_id IN (17)) > 0
当你这样做时:
HAVING interests IN (17)
然后您将字符串与数字进行比较。字符串以静默方式转换为数字。在这种情况下,只转换第一个元素。因此,如果interests
以&#34; 17开头,&#34;然后它匹配,否则它不匹配。
另请注意,只要没有太多的兴趣和技能,您在distinct
中使用group_concat()
的方法就可以了。如果每个空缺有100个,那么中间结果将有10,000行 - 并且需要更长的时间来处理。然而,只有少数几个,方法很好。