尝试使用三个表创建子查询

时间:2014-11-09 23:30:05

标签: mysql

您好我使用以下查询让用户搜索订单:

SELECT orders.*, tasks_x.task_all
        FROM orders LEFT JOIN (SELECT GROUP_CONCAT(tasks.task_name SEPARATOR ",")
            AS task_all, ordertasks.id_order 
                FROM tasks JOIN ordertasks 
                on ordertasks.id_task = tasks.id GROUP BY ordertasks.id_order) as tasks_x
                ON tasks_x.id_order = orders.id WHERE orders.order_name 
                LIKE "%keyword%" OR tasks_x.task_all LIKE "%keyword%"

他们可以通过订单名称或与他们搜索的订单相关联的任务名称搜索订单。但现在我也希望他们可以通过公司名称搜索订单。

这是我的客户表: http://i.imgur.com/dn98QAY.png

如果你需要,这是我的其他表:

订单:

http://i.imgur.com/l9MaQJY.png

为orderTasks:

http://i.imgur.com/JGVqZ2h.png

任务:

http://i.imgur.com/5ywbOk1.png

我还把查询和我的表放在sqlfiddle这里是链接:

http://sqlfiddle.com/#!2/7d942/2

说实话,我已经从我的实习主管那里得到了帮助,可以创建上面找到的子查询。所以我不知道如何实现这一目标。我想我知道如何使用连接执行此操作,但不知道如何使用子查询。但我很高兴想知道如何通过子查询实现这一目标。

1 个答案:

答案 0 :(得分:1)

如果(任务或ordertasks)的订单之间的关系是1:1,则此查询应该执行没有子查询的技巧

SELECT o.*, t.task_name
FROM orders AS o
LEFT JOIN clients AS c ON c.id = o.id_client
LEFT JOIN ordertasks AS x on x.id_order = o.id
LEFT JOIN tasks AS t ON t.id = x.id_order
WHERE o.order_name LIKE "%keyword%" 
OR t.task_name LIKE "%keyword%" 
OR c.companyName LIKE "%keyword%";

如果(任务或ordertasks)的订单之间的关系是1:n,其中n可以大于1,那么这个查询应该做的伎俩

SELECT c.companyName, x.task_all, o.*
FROM orders AS o 
LEFT JOIN (
    SELECT GROUP_CONCAT(t.task_name) AS task_all, x.id_order 
    FROM tasks AS t
    INNER JOIN ordertasks AS x on x.id_task = t.id
    WHERE t.task_name LIKE "%wau%"
    GROUP BY x.id_order
) AS x ON x.id_order = o.id
LEFT JOIN clients AS c ON c.id = o.id_client
WHERE o.order_name LIKE "%wau%" 
OR x.id_order IS NOT NULL
OR c.companyName LIKE "%wau%"

注意:我不同意使用LIKE操作来查找记录,因为LIKE "%keyword%"将不使用索引“这意味着MySQL每次都会对每个表执行一次整表扫描”。如果表中有大量记录,尝试使用LIKE进行搜索将非常慢

提高速度,您可以对列使用全文索引,然后使用MATCH() AGAINST()逻辑来搜索记录,而不是使用LIKE

如果你想走这条路,那你就可以做以下的

  1. 在orders.order_name
  2. 上添加FULLTEXT INDEX
  3. 在task.task_name
  4. 上添加FULLTEXT INDEX
  5. 在clients.companyName
  6. 上添加FULLTEXT INDEX

    以下是您必须运行的查询

    ALTER TABLE orders ADD FULLTEXT INDEX order_name (order_name);
    ALTER TABLE tasks ADD FULLTEXT INDEX task_name (task_name);
    ALTER TABLE tasks ADD FULLTEXT INDEX company_name (companyName);
    

    然后第一个查询将是这样的

    SELECT o.*, t.task_name
    FROM orders AS o
    LEFT JOIN clients AS c ON c.id = o.id_client
    LEFT JOIN ordertasks AS x on x.id_order = o.id
    LEFT JOIN tasks AS t ON t.id = x.id_order
    WHERE MATCH('keyword') AGAINST(o.order_name)
    OR MATCH('keyword') AGAINST(t.task_name)
    OR MATCH('keyword') AGAINST(c.companyName);
    

    第二个选项将是这样的

    SELECT c.companyName, x.task_all, o.*
    FROM orders AS o 
    LEFT JOIN (
        SELECT GROUP_CONCAT(t.task_name) AS task_all, x.id_order 
        FROM tasks AS t
        INNER JOIN ordertasks AS x on x.id_task = t.id
        WHERE MATCH('wau') AGAINST(t.task_name)
        GROUP BY x.id_order
    ) AS x ON x.id_order = o.id
    LEFT JOIN clients AS c ON c.id = o.id_client
    WHERE o.order_name LIKE "%wau%" 
    OR x.id_order IS NOT NULL
    OR c.companyName LIKE "%wau%"