【问题标题】:MATCH many rows against many rows within SQL query and find percentile match?MATCH 许多行与 SQL 查询中的许多行并找到百分位数匹配?
【发布时间】:2014-03-30 21:34:04
【问题描述】:

目前我正在建立一个招聘平台。雇主可以发布工作并接收申请。雇主可以设置求职者必须匹配的许多技能要求。求职者还可以添加他们拥有的许多技能。

我试图找出每个 jobseekers_skills 中有多少与每个作业的 employer_requirements 匹配,以便在视图中显示百分位数匹配。理想情况下,我希望根据jobseeker_skills 表和employer_requirements 表中存在的skill_string 找到匹配项

这是 3 个表中每一个的数据库排列:

应用:

id | job_string | jobseeker_string | employer_string | application_string | date_created

雇主要求:

id | skill_name | requirement_level | skill_string | job_string | employer_string | date_created

求职者技能:

id | skill_name | level | jobseeker_string | skill_string | string | date_created

我有以下代码,它根据传递的“$job_str”获取所有applications。下面的代码只是一个简单的get,但不确定从这里去哪里。

function skills_match($job_str){

    $this->db->select('*')
             ->from('applications')
             ->where('job_string', $job_str)
             ->join('users', 'users.string = applications.jobseeker_string', 'left');

    $applications = $this->db->get();

    return $applications;

}

应用程序表 - 示例数据: +--------+------------------+------------------+------------------+ | id | job_string | jobseeker_string | employer_string | +--------+------------------+------------------+------------------+ | 1 | vs71FVTBb12DdGlf | uMIsuDJaBuDmo8iq | biQxyPekn6iayIgm | | 2 | vs71FVTBb12DdGlf | x7phHsVnwJ1K1yHy | biQxyPekn6iayIgm | | 3 | vs71FVTBb12DdGlf | Fm1TIJLxz6Xg6QPk | biQxyPekn6iayIgm | +--------+------------------+------+-----+---------+-------+------+

雇主要求 - 样本数据:

+--------+------------------+-------------+------------------+------------------+ | id | job_string | skill_name | skill_string | employer_string | +--------+------------------+-------------+------------------+-----------------+| | 1 | vs71FVTBb12DdGlf |PHP | 9Y8XeCWqJXzkZ5dD | biQxyPekn6iayIgm | | 2 | vs71FVTBb12DdGlf |JavaScript | O6es19t5CgcRHvct | biQxyPekn6iayIgm | | 3 | vs71FVTBb12DdGlf |HTML | wx4evsXC62BWiN7p | biQxyPekn6iayIgm | | 4 | vs71FVTBb12DdGlf |Python | jx15rH1vrGLmsVmq | biQxyPekn6iayIgm | | 5 | vs71FVTBb12DdGlf |SQL | EksP7mEip0Hs4zKd | biQxyPekn6iayIgm | | 6 | vs71FVTBb12DdGlf |LESS | fj40m4hkiuDGtbzr | biQxyPekn6iayIgm | +--------+------------------+-------------+------+-----+---------+-------+------+ 求职者技能 - 样本数据:

+--------+------------------+------------------+------------------+ | id | jobseeker_string | skill_name | skill_string | +--------+------------------+------------------+------------------+ | 1 | uMIsuDJaBuDmo8iq | PHP | 9Y8XeCWqJXzkZ5dD | | 2 | uMIsuDJaBuDmo8iq | Backbone | 4VIiAxZoL1VbPnTa | | 3 | x7phHsVnwJ1K1yHy | LESS | fj40m4hkiuDGtbzr | | 2 | x7phHsVnwJ1K1yHy | Ruby | gTZg4fwYuzMMFcBw | | 3 | x7phHsVnwJ1K1yHy | SQL | EksP7mEip0Hs4zKd | | 1 | Fm1TIJLxz6Xg6QPk | PHP | 9Y8XeCWqJXzkZ5dD | | 2 | Fm1TIJLxz6Xg6QPk | Python | jx15rH1vrGLmsVmq | | 3 | Fm1TIJLxz6Xg6QPk | HTML | wx4evsXC62BWiN7p | | 3 | Fm1TIJLxz6Xg6QPk | Git | aR9B9ns1sHlGrzFw | +--------+------------------+------+-----+---------+-------+------+

根据以上内容,this 应该输出百分比或数字。匹配的技能:

应用程序 - 以下是每个应用程序匹配技能的数量/百分比: uMIsuDJaBuDmo8iq - 1/6 (16.666%) x7phHsVnwJ1K1yHy - 2/6 (33.333%) Fm1TIJLxz6Xg6QPk - 3/6 (50%)

任何问题,然后请开火。提前感谢您的帮助。

【问题讨论】:

  • 能否提供几行样本数据,几行想要的结果?
  • @OllieJones 我刚刚使用示例数据和预期结果的简要摘要进行了编辑,如果您需要其他任何内容,请尽管询问。
  • @OllieJones 明确表示,我仍然希望获得特定工作的所有申请,但只是 order_by 具有最佳匹配技能的求职者
  • @OllieJones 我很好奇你是否对这个问题有任何见解,因为我在过去 2 天里一直被困并且无处可去

标签: mysql sql database codeigniter active-record-query


【解决方案1】:

首先,这是两个问题:

  1. 哪些申请人最适合我的业务
  2. 哪些雇主最符合我的技能。

这两个问题可能看起来相同,但实际上并非如此。

第一个问题: 我想要所有符合我任何要求的申请人,按我的要求数量排序。首先我得到所有匹配项:

select *
from Requirements r 
inner join Jobseeker j
on r.skill_string = j.r.skill_string 
where job_string = 'vs71FVTBb12DdGlf';

然后我将 em 分组,计数 em 等:

select 
  jobseeker_string, 
  count(1) / (select count(1) from Requirements where job_string = 'vs71FVTBb12DdGlf') as match_percentage
from Requirements r 
inner join Jobseeker j
on r.skill_string = j.r.skill_string 
where job_string = 'vs71FVTBb12DdGlf'
group by jobseeker_string;

第二个问题:有点困难,因为申请人可能想知道他/她是否符合一定比例的工作技能,以及他自己的技能(这可能适用于第一个问题也是)。如下查询:

select 
  job_string, 
  count(1) / (select count(1) from Requirements where jobseeker_string  = 'uMIsuDJaBuDmo8iq') as my_match,
  count(1) / (select count(1) from Requirements where job_string = r.job_string) as job_match
from Requirements r 
inner join Jobseeker j
on r.skill_string = j.r.skill_string 
where jobseeker_string = 'uMIsuDJaBuDmo8iq'
group by job_string;

请注意:查询是我写的,可能包含一些拼写错误

如果你想订购,你可以这样做:

select * from
  ([[insert the above query here]]) t
order by field.

综合:

select 
  job_string, 
  jobseeker_string
  count(1) / (select count(1) from Requirements where jobseeker_string  = r.jobseeker_string ) as seeker_match,
  count(1) / (select count(1) from Requirements where job_string = r.job_string) as job_match
from Requirements r 
inner join Jobseeker j
on r.skill_string = j.r.skill_string 
group by job_string, jobseeker_string;

应用程序

select * from 
  (select 
    job_string, 
    jobseeker_string
    count(1) / (select count(1) from Requirements where jobseeker_string  = r.jobseeker_string ) as seeker_match,
    count(1) / (select count(1) from Requirements where job_string = r.job_string) as job_match
  from Requirements r 
  inner join Jobseeker j
  on r.skill_string = j.r.skill_string 
  group by job_string, jobseeker_string) t
inner join applications a
on t.job_string = a.job_string and t.jobseeker_string = a.t.jobseeker_string

【讨论】:

  • 首先,非常感谢您抽出宝贵的时间。不过,我认为你不明白这个问题。我有很多应用程序,我希望能够查看所有这些应用程序,无论它们是否匹配。对于每个应用程序,我想找出有多少求职者技能与该特定工作的雇主要求相匹配。
  • 添加了一个组合查询,它返回每个职位的所有求职者的列表,以及他们各自的匹配百分比。
  • 这仍然行不通,因为您没有考虑到applications 表,我实际上在该表中找出了谁申请了这份工作。从他们那里,我会得到jobseeker_skills,基于applications.jobseeker_string = jobseeker_skills.jobseeker_string 之间的某种连接,并得到employer_requirementsapplications.job_string = employer_requirements.job_string 类似的东西。所以应用程序表很重要
  • 如果你能看看上面的示例数据会很棒,因为我可能会在某个地方误导你
  • 我最终意识到你的方法有效,所以我打算给你赏金。最初看它时,我只是没有动脑筋。
【解决方案2】:

MySQL 为您提供了一种很好的方式来进行分组(if 和 average)。 你玩过 AVG(IF(..) 吗?

假设您有两个包含几列的表。

类似这样的东西(抱歉,sqlfiddle 没用了):

first_table:

id  category    element
1   number  two
2   number  three
3   number  four
4   number  five
5   number  eleven
6   fruit   banana
7   fruit   pineapple
8   fruit   pear
9   fruit   strawberry

second_table:

id  category    element
1   number  one
2   number  five
3   number  six
4   number  seven
5   number  three
6   fruit   apple
7   fruit   banana

1) 你想知道第一个表有多少元素可以在第二个中找到:

    select count(*) as total
    from first_table t1 
    join second_table t2 
    on t1.element = t2.element

会回来

 total
 3

2) 使用左连接,您可能会获得有价值的信息:

    select 
        count(*) as total, 
        count(t2.element) as number_matching
    from first_table t1
    left join second_table t2
    on t1.element = t2.element

这将为您提供元素总数以及匹配的元素数。除法,你有百分比。

  total    number_matching
  9        3

3) 用avg和if,我们可以直接得到0和1之间的比例:

    select
        AVG(IF(t2.element IS NULL, 0, 1)) as proportion_matching
    from first_table t1
    left join second_table t2
    on t1.element = t2.element

返回

proportion_matching
0.33333

4) 格式为百分比,四舍五入...

    select
        ROUND(AVG(IF(t2.element IS NULL, 0, 1)) * 100, 1) as percent_matching
    from first_table t1
    left join second_table t2
    on t1.element = t2.element

你得到

percent_matching
33.3

5) 您实际上可以按类别分隔结果。

    select
        t1.category,
        ROUND(AVG(IF(t2.element IS NULL, 0, 1)) * 100, 1) as percent_matching
    from first_table t1
    left join second_table t2
    on t1.element = t2.element
    group by t1.category

请记住,这实际上是“表 2 中可以找到的表 1 中元素的百分比”

category  percent_matching
fruit     25.0
number    40.0

6) 将其应用于应用程序和技能集... 您将按以下方式审核求职者申请:

    SELECT
        a.job_string,
        ROUND(AVG(IF(jobseeker.skill_string IS NULL, 0, 1)) * 100, 1) as percent_matching
    FROM application a  
    JOIN employer_requirements er
    ON er.job_string = a.job_string
    LEFT JOIN jobseeker js
    ON a.jobseeker_string = js.jobseeker_string
    GROUP BY a.job_string

7) 当然,您可以根据需要在 where 中过滤您的工作字符串。 事实上,这里添加的与应用程序表的连接只是确保您只获得用户实际申请的工作的结果。但是如果你已经有一个job_string,你可以逃脱:

    SELECT
        er.job_string,
        ROUND(AVG(IF(jobseeker.skill_string IS NULL, 0, 1)) * 100, 1) as percent_matching
    FROM        employer_requirements er    
    LEFT JOIN   jobseeker js
    ON          js.jobseeker_string = er.jobseeker_string
    WHERE       er.jobseeker_string = ?

7) 我让你把它扔到一个活动记录查询中(这不是我最了解的部分;)

【讨论】:

  • 谢谢。我非常感谢您抽出宝贵的时间,但我一直在使用原始答案,并发现当我开始使用它时它确实有效。我会拿很多你给我看的东西,试着把它融入我的工作中,再次感谢你抽出时间。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-08-11
  • 2016-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-12
  • 1970-01-01
相关资源
最近更新 更多