3

2 つのテーブルがあります。1 つは候補者とそのスキル用、もう 1 つは仕事とその仕事に必要なスキル用です。たとえば、次のようになります。

CSID = 候補スキル ID (PK)
CID = 候補 ID (FK)
S_CODE = スキル コード (FK)

これが候補者_スキルテーブルです

+------------+---------+---------+
| CSID       | CID     |  S_CODE |
+------------+---------+---------+
| 1          | 1       | 5       |
| 2          | 1       | 9       |
| 3          | 2       | 5       |
| 4          | 2       | 10      |
+------------+---------+---------+

SJID = スキルジョブ ID (PK)
JID = ジョブ ID (FK)
S_CODE = スキルコード (FK)

skill_job テーブルは次のとおりです。

+------------+---------+---------+
| SJID       | JID     |  S_CODE |
+------------+---------+---------+
| 12         | 50      | 5       |
| 13         | 50      | 9       |
| 14         | 51      | 1       |
| 15         | 52      | 10      |
+------------+---------+---------+

したがって、この例では、スキル コード (S_CODE) が両方とも 5 と 9 であるため、ジョブ 50 の唯一の候補者は 1 ですが、必要なジョブがあるため、候補者 2 も 52 に一致するようにしたいと考えています。スキルと追加のスキル。仕事と候補者を一致させるためにいくつかの方法を試しましたが、失敗しています。そのような方法の例は、以下のコードです:

    SELECT * , COUNT(skill_job.S_CODE) AS cnt FROM candidate_skill,
 skill_job WHERE candidate_skill.S_CODE = skill_job.S_CODE HAVING (cnt >=2)

問題は、見つかった候補者を 1 つだけに制限し、COUNT 句を削除すると、1 つのスキルのみに一致するすべての候補者がリストされるため、候補者 2 もジョブ 50 に一致することです。

phpmyadmin からのテーブルの mysql コードは次のとおりです。

    -- phpMyAdmin SQL Dump
-- version 3.4.5
-- http://www.phpmyadmin.net
--
-- Host: localhost
-- Generation Time: Jul 16, 2012 at 09:27 PM
-- Server version: 5.5.16
-- PHP Version: 5.3.8

SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";


/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;

--
-- Database: `employment`
--

-- --------------------------------------------------------

--
-- Table structure for table `candidate`
--

CREATE TABLE IF NOT EXISTS `candidate` (
  `CID` int(4) NOT NULL AUTO_INCREMENT,
  `title` varchar(5) NOT NULL,
  `fname` varchar(30) NOT NULL,
  `lname` varchar(30) NOT NULL,
  `dob` date NOT NULL,
  `email` varchar(50) NOT NULL,
  `address` varchar(255) NOT NULL,
  `city` varchar(50) NOT NULL,
  `postcode` varchar(10) NOT NULL,
  `phone_num` varchar(11) NOT NULL,
  `username` varchar(40) NOT NULL,
  `password` varchar(40) NOT NULL,
  `regdate` datetime NOT NULL,
  `acc_type` enum('c','s') NOT NULL DEFAULT 'c',
  `emailactivate` enum('0','1') NOT NULL DEFAULT '0',
  `cv_name` varchar(60) NOT NULL,
  `cv` blob NOT NULL,
  PRIMARY KEY (`CID`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 COMMENT='// this is the table for the candidates' AUTO_INCREMENT=175 ;

--
-- Dumping data for table `candidate`
--

INSERT INTO `candidate` (`CID`, `title`, `fname`, `lname`, `dob`, `email`, `address`, `city`, `postcode`, `phone_num`, `username`, `password`, `regdate`, `acc_type`, `emailactivate`, `cv_name`, `cv`) VALUES
(128, 'Mr', 'clement', 'Chilingulo', '0000-00-00', 'chlngl@yahoo.com', '28 oakfield Road', 'london', 'E6 1LW', '07771611873', 'casante', 'b59c67bf196a4758191e42f76670ceba', '0000-00-00 00:00:00', 'c', '0', '', '');
INSERT INTO `candidate` (`CID`, `title`, `fname`, `lname`, `dob`, `email`, `address`, `city`, `postcode`, `phone_num`, `username`, `password`, `regdate`, `acc_type`, `emailactivate`, `cv_name`, `cv`) VALUES
(134, 'Mr', 'rverv', 'revrb', '0000-00-00', 'tdbsdrt', 'trsbrtd', 'trbtrtrb', 'tbrfbgrts', 'trfbtrgbrfg', 'clement', 'b59c67bf196a4758191e42f76670ceba', '0000-00-00 00:00:00', 's', '0', '', '');
INSERT INTO `candidate` (`CID`, `title`, `fname`, `lname`, `dob`, `email`, `address`, `city`, `postcode`, `phone_num`, `username`, `password`, `regdate`, `acc_type`, `emailactivate`, `cv_name`, `cv`) VALUES
(165, 'Mr', 'oinInINOioni', 'ioin', '0000-00-00', 'inioimn', 'in', 'oin', 'oni', 'io', 'k', '7b8b965ad4bca0e41ab51de7b31363a1', '0000-00-00 00:00:00', 'c', '0', '', ''),
(166, 'Mr', 'pjINoNlkinoinoi', 'ino', '0000-00-00', 'oimpnponi', 'inoi', 'no', 'nj', 'nio', 'nio', 'eb5bc837d01b911029ae378e8a1c9f5d', '0000-00-00 00:00:00', 'c', '0', '', ''),
(167, 'Mr', 'vrae', 'ergvaer', '0000-00-00', 'aerbg', 'aergvera', 'aergvrea', 'aergvear', 'aergarev', 'grebvarvf', '609c1b136ec8d0d2dfdf9a2105fb605f', '0000-00-00 00:00:00', 'c', '0', '', ''),
(168, 'Mr', 'vrae', 'ergvaer', '0000-00-00', 'aerbg', 'aergvera', 'aergvrea', 'aergvear', 'aergarev', 'grebvarvf', '609c1b136ec8d0d2dfdf9a2105fb605f', '0000-00-00 00:00:00', 'c', '0', '', ''),
(169, 'Mr', 'ubp', 'bu', '0000-00-00', 'ubip', ';ub', 'ubi', 'ubo', 'buo', 'ubiipbu', '9f44ce1389a3e7372834ed730b559a5e', '0000-00-00 00:00:00', 'c', '0', '', ''),
(170, 'Mr', 'rvev', 'ferhbgetb', '0000-00-00', 'tsbtrb', 'trbstrb', 'trbsfb ', 'stb stb', 'vvfs', 'csdcdsvarewdcv', 'd41d8cd98f00b204e9800998ecf8427e', '0000-00-00 00:00:00', 'c', '0', '', ''),
(171, 'Mr', 'rvev', 'ferhbgetb', '0000-00-00', 'tsbtrb', 'trbstrb', 'trbsfb ', 'stb stb', 'vvfs', 'csdcdsvarewdcv', 'd41d8cd98f00b204e9800998ecf8427e', '0000-00-00 00:00:00', 'c', '0', '', ''),
(172, '', '', '', '0000-00-00', '', '', '', '', '', '', 'd41d8cd98f00b204e9800998ecf8427e', '0000-00-00 00:00:00', 'c', '0', '', ''),
(173, '', 'dds', 'vrv av', '0000-00-00', 'rvear', 'vreverav', 'rvedfsdv', 'frvdvf', 'fveavd', 'vdrareavdv', '84c71ac76340092398a1ed4bc7d6fe19', '0000-00-00 00:00:00', 'c', '0', '', ''),
(174, '', 'dds', 'vrv av', '0000-00-00', 'rvedwear', 'vreverav', 'rvedfsdv', 'frvdvf', 'fveavd', 'vdraredfcavdv', 'd41d8cd98f00b204e9800998ecf8427e', '0000-00-00 00:00:00', 'c', '0', '', '');

-- --------------------------------------------------------

--
-- Table structure for table `candidate_skill`
--

CREATE TABLE IF NOT EXISTS `candidate_skill` (
  `CSID` int(4) NOT NULL AUTO_INCREMENT,
  `CID` int(4) NOT NULL,
  `S_CODE` int(4) NOT NULL,
  PRIMARY KEY (`CSID`),
  KEY `CID` (`CID`),
  KEY `S_CODE` (`S_CODE`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 COMMENT='//match candidate and skill' AUTO_INCREMENT=131 ;

--
-- Dumping data for table `candidate_skill`
--

INSERT INTO `candidate_skill` (`CSID`, `CID`, `S_CODE`) VALUES
(114, 134, 2),
(116, 134, 9),
(121, 134, 5),
(126, 128, 1);

-- --------------------------------------------------------

--
-- Table structure for table `job`
--

CREATE TABLE IF NOT EXISTS `job` (
  `JID` int(4) NOT NULL AUTO_INCREMENT,
  `job_title` varchar(40) NOT NULL,
  `job_desc` varchar(255) NOT NULL,
  `start_date` date NOT NULL,
  `end_date` date NOT NULL,
  PRIMARY KEY (`JID`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 COMMENT='// this is the table for the job vacancies' AUTO_INCREMENT=10 ;

--
-- Dumping data for table `job`
--

INSERT INTO `job` (`JID`, `job_title`, `job_desc`, `start_date`, `end_date`) VALUES
(1, 'engineer', ' fix engineering ish that is messed ', '0000-00-00', '0000-00-00'),
(5, 'pilot', '', '0000-00-00', '0000-00-00'),
(8, 'Charity Helper', ' ', '0000-00-00', '0000-00-00'),
(9, 'accountant', '  ', '0000-00-00', '0000-00-00');

-- --------------------------------------------------------

--
-- Table structure for table `skill`
--

CREATE TABLE IF NOT EXISTS `skill` (
  `S_CODE` int(4) NOT NULL AUTO_INCREMENT COMMENT '// this is the skill primary key',
  `skill_name` varchar(40) NOT NULL,
  `skill_desc` varchar(255) NOT NULL,
  PRIMARY KEY (`S_CODE`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=11 ;

--
-- Dumping data for table `skill`
--

INSERT INTO `skill` (`S_CODE`, `skill_name`, `skill_desc`) VALUES
(1, 'speaking', 'English is your first language'),
(2, '  writing', 'You can write English very well'),
(3, ' public', ''),
(5, 'initiative', ''),
(6, 'interviewing', ''),
(7, 'negotiating', ''),
(8, 'leading', ''),
(9, '  energy', ''),
(10, ' organisation', '');

-- --------------------------------------------------------

--
-- Table structure for table `skill_job`
--

CREATE TABLE IF NOT EXISTS `skill_job` (
  `SJID` int(4) NOT NULL AUTO_INCREMENT,
  `JID` int(4) NOT NULL,
  `S_CODE` int(4) NOT NULL,
  PRIMARY KEY (`SJID`),
  KEY `S_CODE` (`S_CODE`),
  KEY `JID` (`JID`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=106 ;

--
-- Dumping data for table `skill_job`
--

INSERT INTO `skill_job` (`SJID`, `JID`, `S_CODE`) VALUES
(91, 5, 2),
(94, 5, 5),
(95, 5, 9),
(98, 1, 1),
(102, 1, 8),
(105, 8, 8);

--
-- Constraints for dumped tables
--

--
-- Constraints for table `candidate_skill`
--
ALTER TABLE `candidate_skill`
  ADD CONSTRAINT `candidate_skill_ibfk_3` FOREIGN KEY (`CID`) REFERENCES `candidate` (`CID`) ON DELETE CASCADE ON UPDATE CASCADE,
  ADD CONSTRAINT `candidate_skill_ibfk_4` FOREIGN KEY (`S_CODE`) REFERENCES `skill` (`S_CODE`) ON DELETE CASCADE ON UPDATE CASCADE;

--
-- Constraints for table `skill_job`
--
ALTER TABLE `skill_job`
  ADD CONSTRAINT `skill_job_ibfk_4` FOREIGN KEY (`JID`) REFERENCES `job` (`JID`) ON DELETE CASCADE ON UPDATE CASCADE,
  ADD CONSTRAINT `skill_job_ibfk_5` FOREIGN KEY (`S_CODE`) REFERENCES `skill` (`S_CODE`) ON DELETE CASCADE ON UPDATE CASCADE;

/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
4

5 に答える 5

4

二重否定はあなたの友人です (ただし、MySQL がそれをサポートしているかどうかを判断できるほど、私は MySQL をよく知りません):

SELECT DISTINCT CS.CID, SJ.JID
FROM CANDIDATE_SKILL CS
JOIN SKILL_JOB SJ ON CS.S_CODE = SJ.S_CODE
WHERE NOT EXISTS(SELECT 1
                 FROM SKILL_JOB SJ2
                 WHERE SJ.JID = SJ2.JID
                   AND NOT EXISTS(SELECT 1
                                  FROM CANDIDATE_SKILL CS2
                                  WHERE CS.CID = CS2.CID
                                    AND SJ2.S_CODE = CS2.S_CODE))

これの「人間の翻訳」は、候補者が持っていない仕事に必要なスキルが存在してはならないということです。

于 2012-07-16T19:31:53.573 に答える
1

INNER JOINを使用して 2 つのテーブルを結合し、それらの行の値を比較する必要があるようです。

于 2012-07-16T19:11:47.990 に答える
0

もう少し複雑な JOIN が必要になります。あなたの要求と、「候補者 X はどのように仕事 Y にマッチするのか?」という明白な要求に同時に答える簡単な方法はないと思います。および「候補者 X は仕事 Y にどのくらい適合しますか?」。

とにかく、ここに行きます。

SELECT candidate_skill.CID, skill_job.JID, COUNT(*) AS has, sjtot.needed
    FROM skill_job JOIN candidate_skill ON (candidate_skill.S_CODE = skill_job.S_CODE)
    LEFT JOIN ( SELECT JID, COUNT(*) AS needed FROM skill_job GROUP BY JID ) AS sjtot
        ON ( skill_job.JID = sjtot.JID )
GROUP BY CID, JID
HAVING has >= needed;

実際には、最初に、skill_job で必要なスキルをグループ化します。これにより、ジョブ 50 には 2 つのスキルが必要であることがわかります。

これを武器に、必要なスキルと候補スキルを LEFT JOIN します。すべてのスキルに参加する候補者もいれば、参加しない候補者もいます。あとは、一致する数を数えるだけです。

+------+------+-----+--------+
| CID  | JID  | has | needed |
+------+------+-----+--------+
|    1 |   50 |   2 |      2 |
|    2 |   52 |   1 |      1 |
+------+------+-----+--------+

考え直して、必要なスキル レベルと提供されたスキル レベルを選択し、CASE WHEN を使用して一致を抽出することができます (提供される場合は 1 >= 必須、それ以外の場合は提供/必須)。結果の値の平均は、「スキル一致」インデックスとして使用される場合があります。

「X は Y に対してどのように一致するか」については、質問、候補 CID 1 がジョブ JID 50 に適していることがわかったら、候補とジョブの間で LEFT JOIN を実行できます。仕事で求められるものは何でも、候補者が持っていることは既にわかっていますが、このようにして、候補者が持っている求められていないスキルと、その他の関連する値も取得します。

上記のクエリとこの最後のクエリを結合するネストされたクエリは、おそらくすべてを一挙に教えてくれるでしょうが、それはコストのかかる急襲になると思います:-)

于 2012-07-16T19:38:58.573 に答える
0

このようなものでなければなりません..

SELECT
   CID
FROM 
   candidate_skill
WHERE
   S_CODE IN (
               SELECT S_CODE FROM skill_jobs where JID = 52 
             )
GROUP BY CID

訂正: 前のクエリは、必要なすべての S_CODE と一致しません

SELECT
   CID, COUNT(CSID) as cnt
FROM 
   candidate_skill
INNER JOIN skill_jobs 
WHERE
   S_CODE IN (
               SELECT S_CODE FROM skill_jobs where JID = 52 
             )
GROUP BY CID 
HAVING cnt = (
               SELECT count(*) from skill_jobs where JID = 52
             )
于 2012-07-16T19:18:17.147 に答える
0

クロス dbms のサポートを気にしない場合は、mysql 固有の group_concat を使用して、2 つの s_code セットを文字列に減らし、候補者/ジョブごとに 1 つずつ、次のように比較することができます。

select * from 
(select cs.cid, group_concat(cs.s_code order by cs.s_code) skills 
    from candidate_skill cs group by cs.cid) cs, 
(select sj.jid, group_concat(sj.s_code order by sj.s_code) skills 
    from skill_job sj group by sj.jid) sj
where sj.skills = cs.skills

テーブルが最終的に成長すると、ますます遅くなり、group_concat() で作成されたフィールドにインデックスを作成できないことに注意してください。

于 2012-07-16T19:47:28.257 に答える