有没有更好的方法来执行此查询?

时间:2013-11-26 03:01:05

标签: mysql performance

我是MYSQL的新手,这个查询有效,但想知道是否有更有效的方法。 我有2个表... client_table client_skills 。两个表都有一个'client_id'列。我正在尝试仅选择与所有请求的技能代码和类型匹配的客户端

这是我第一次尝试的...(除非你将AND改为OR,否则不起作用)

SELECT * FROM client_table
LEFT JOIN client_skills ON client_table.client_id = client_skills.client_id
WHERE (skill_code='97' AND skill_type='0')
AND (skill_code='65' AND skill_type='0')
AND (skill_code='23' AND skill_type='5')

然后我尝试了这个......(它可以工作并返回我想要的结果)

SELECT * FROM client_table
WHERE client_id IN 
(SELECT client_id FROM client_skills WHERE (skill_code='97' AND skill_type='0'))
AND client_id IN
(SELECT client_id FROM client_skills WHERE (skill_code='65' AND skill_type='0'))
AND client_id IN
(SELECT client_id FROM client_skills WHERE (skill_code='23' AND skill_type='5'))

但如果有更短或更有效的方法,我很乐意学习它。 谢谢你的帮助

4 个答案:

答案 0 :(得分:0)

第二个比第一个慢,因为你正在进行4次查询,所以在这两个例子中,只需用OR而不是AND去第一个。

可能有更好/更快的查询,但这取决于要求和表的索引

例如,你真的需要skill_type吗?你有两种相同代码和不同类型的技能吗?如果所有技能代码都不同,请执行以下操作:

SELECT * FROM client_table
LEFT JOIN client_skills ON client_table.client_id = client_skills.client_id
WHERE skill_code IN ('97','65','23')

如果你有关于skill_code的索引,那么查询也会更快

编辑:好的,现在我理解你的问题,你需要至少2个查询,一个用于获得与树技能相匹配的所有客户ID,另一个用于获得具有这些ID的客户,请尝试以下操作:

SELECT * from client_table WHERE client_id IN (
  SELECT client_id FROM client_skills WHERE (skill_code='97' AND skill_type='0') OR 
  (skill_code='65' AND skill_type='0') OR (skill_code='23' AND skill_type='5')
  GROUP BY client_id HAVING count(*) = 3)

你在做什么:

  1. 让所有client_skills记录您所需的三项技能中的任何一项
  2. 按client_id
  3. 对它们进行分组
  4. 仅为具有3条记录的组选择client_id(这意味着这些组具有所有三种技能)
  5. 选择子查询返回的ID中所有id的所有客户端
  6. 我认为这是最快的方法,只有2个查询,我不认为只用一个查询就可以完成

    注意:该查询未经过测试,这是您的想法,您可能需要与HAVING和GROUP_BY一起玩一下

答案 1 :(得分:0)

使用OR修改的第一个查询也不错。你可以使用UNION

SELECT client_id FROM client_skills WHERE (skill_code='97' AND skill_type='0')
UNION
SELECT client_id FROM client_skills WHERE (skill_code='65' AND skill_type='0')
UNION
SELECT client_id FROM client_skills WHERE (skill_code='23' AND skill_type='5')

EDITED

你可以做到这样的事情。 SELF JOIN是必需的。 (未对您的数据进行测试):

SELECT t1.client_id
FROM client_skills t1 JOIN client_skills t2 ON t1.client_id = t2.client_id
            AND t1.skill_code='97' AND t1.skill_type='0'
            AND t2.skil_code='65' AND t2.skill_type='0'
    JOIN client_skills t3 ON t3.client_id = t1.client_id
            AND t3.skil_code='23' AND t3.skill_type='5'

答案 2 :(得分:0)

这是您要求的,因为您想使用AND代替OR sqlFiddle example仅在我的示例中杰夫拥有所有3项技能(技能代码和技能类型)

SELECT c.*
FROM client_table c,
     client_skills s1,
     client_skills s2,
     client_skills s3
WHERE
      c.client_id = s1.client_id AND s1.skill_code=97 AND s1.skill_type=0
  AND c.client_id = s2.client_id AND s2.skill_code=65 AND s2.skill_type=0
  AND c.client_id = s3.client_id AND s3.skill_code=23 AND s3.skill_type=5

它与您的第二个查询的逻辑相同。

答案 3 :(得分:0)

SELECT
    client_table.*
    ,SUM(
        IF( skill_code='97' AND skill_type='0' ,1 ,0 )
        +
        IF( skill_code='65' AND skill_type='0' ,1 ,0 )
        +
        IF( skill_code='23' AND skill_type='5' ,1 ,0 )
    ) AS skill_code_type_count
FROM
    client_table
    LEFT JOIN client_skills ON client_table.client_id = client_skills.client_id
GROUP BY
    client_table.client_id
HAVING
    skill_code_type_count >= 3