Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 尝试使用三个表进行子查询_Mysql - Fatal编程技术网

Mysql 尝试使用三个表进行子查询

Mysql 尝试使用三个表进行子查询,mysql,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 ordert

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

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%"
他们可以通过订单名称或链接到他们正在搜索的订单的任务名称来搜索订单。但现在我还希望他们可以通过公司名称搜索订单

这是我的客户表:

如果您需要,这是我的其他桌子:

订单:

订单任务:

任务:

我还将查询和我的表放在SQLFIDLE上,下面是链接:


老实说,我得到了实习主管的帮助,创建了您在上面找到的子查询。所以我不知道如何做到这一点。我想我知道如何使用连接,但不知道如何使用子查询。但是我很想知道如何通过子查询实现这一点。

如果订单与(任务或订单任务)之间的关系是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%";

如果订单与(task或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()对()
逻辑来搜索记录,而不是像
那样使用

如果你想走这条路,那么你必须做以下事情

  • 在orders.order\u名称上添加全文索引
  • 在task.task\u名称上添加全文索引
  • 在clients.companyName上添加全文索引
  • 以下是您必须运行的查询

    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%"
    
    第二种选择是这样的

    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%"
    

    您好,谢谢您的回答,但我认为您只使用联接。我很高兴看到子查询是如何完成的。您说的“it也d”是什么意思“:)?对不起,我的答案似乎在最后被删掉了。我更新了我的答案。为什么需要子查询?数据库中的每个订单是否有多个任务?还有一个想法,如果您只想从orders表返回列,我们可以对查询进行更多的检查以提高效率。我们可以使用exists逻辑检查是否找到匹配项,而不是使用联接。您好,您的子查询可以工作:),但为什么在第一个子查询中使用“is NOT NULL”?因为查询仍然允许我显示已找到的顺序。同样感谢分享全文查询,因为我的MySQL引擎,我无法运行它们。我想我需要一个MyISAM引擎来做全文搜索。但我明天会测试,因为现在我累了。我很高兴他们帮了你。您应该能够使用全文索引。您可以在innodb表上使用FT索引。关于IS NOT NULL,为了使您的查询执行得更好,我将
    t.task\u名称(如“%wau%”)移动到了子查询中。这将减少子查询中返回的数据集。因此,如果在task_名称中找到记录,您希望返回它。查询将查找在
    orders.task\u name
    表中找到的任何内容,以及在
    clients.companyNames
    中找到的任何内容。我们还查找子查询找到的任何记录。我希望这有帮助。