MySQL-按总限制选择每个联合体的相等数量

MySQL-按总限制选择每个联合体的相等数量,mysql,union,sql-limit,Mysql,Union,Sql Limit,在MySQL数据库中,我有3个表:客户、项目和任务。对于我正在实现的搜索,我希望搜索所有3个表并选择“找到匹配项”。问题是我想同样限制MySQL返回的结果数量 这是我当前查询的一个示例: SELECT id, title, type FROM ( ( SELECT id, title, 'customer' AS type, MATCH (title) AGAINST ('+test* ' IN BOOLEAN MODE) AS score FROM customers

在MySQL数据库中,我有3个表:客户、项目和任务。对于我正在实现的搜索,我希望搜索所有3个表并选择“找到匹配项”。问题是我想同样限制MySQL返回的结果数量

这是我当前查询的一个示例:

SELECT id, title, type
FROM (
    (
    SELECT id, title, 'customer' AS type, MATCH (title) AGAINST ('+test* ' IN BOOLEAN MODE) AS score
    FROM customers
    WHERE MATCH (title) AGAINST ('+test* ' IN BOOLEAN MODE)
    )
    UNION DISTINCT
    (
    SELECT id, title, 'project' AS type, MATCH (title) AGAINST ('+test* ' IN BOOLEAN MODE) AS score
    FROM projects
    WHERE MATCH (title) AGAINST ('+test* ' IN BOOLEAN MODE)
    )
    UNION DISTINCT
    (
    SELECT id, title, 'task' AS type, MATCH (title) AGAINST ('+test* ' IN BOOLEAN MODE) AS score
    FROM tasks
    WHERE MATCH (title) AGAINST ('+test* ' IN BOOLEAN MODE)
    )
) res
LIMIT 6;
在本例中,我希望将结果限制为6

本例的预期最终结果如下:

1如果所有表格至少有2个结果,则为每个表格显示2个结果

id     title                      type
20     'First test customer'      'customer'
22     'Test customer 2'          'customer
48     'A project for testing'    'project'
17     'Test Project'             'project'
1      'Task test'                'task'
2      'Second test'              'task'
2如果一个表没有任何结果,则为其他两个表中的每个表显示3个结果。如果只有一个表有结果,则显示该表的6个结果

id     title                      type
20     'First test customer'      'customer'
22     'Test customer 2'          'customer
56     'Customer test 56'         'customer'
1      'Task test'                'task'
2      'Second test'              'task'
3      'Test task'                'task'
3如果其中两个表有两个以上的结果,而第三个表只有一个结果,则显示其中一个表有足够结果的3个结果,两个表中的另一个表有2个结果,只有一个结果的表有1个结果

id     title                      type
20     'First test customer'      'customer'
48     'A project for testing'    'project'
17     'Test Project'             'project'
34     'Testing project'          'project'
1      'Task test'                'task'
2      'Second test'              'task'
有人能帮我吗


提前谢谢

您可以为每个选择使用一个行号,然后将UNION与该计算字段排序,以平衡从单个查询获得的结果。我没有测试此代码,请将其作为起点:

SET @rank1=0;
SET @rank2=0;
SET @rank3=0;
SELECT id, title, type, rank
FROM (
    (

    SELECT @rank1:=@rank1+1 AS rank, id, title, 'customer' AS type, MATCH (title) AGAINST ('+test* ' IN BOOLEAN MODE) AS score
    FROM customers
    WHERE MATCH (title) AGAINST ('+test* ' IN BOOLEAN MODE)
    )
    UNION DISTINCT
    (

    SELECT @rank2:=@rank2+1 AS rank, id, title, 'project' AS type, MATCH (title) AGAINST ('+test* ' IN BOOLEAN MODE) AS score
    FROM projects
    WHERE MATCH (title) AGAINST ('+test* ' IN BOOLEAN MODE)
    )
    UNION DISTINCT
    (

    SELECT @rank3:=@rank3+1 AS rank, id, title, 'task' AS type, MATCH (title) AGAINST ('+test* ' IN BOOLEAN MODE) AS score
    FROM tasks
    WHERE MATCH (title) AGAINST ('+test* ' IN BOOLEAN MODE)
    )
) res
ORDER BY rank 
LIMIT 6;

您可以为每个选择使用一个行号,然后将UNION与该计算字段排序,以平衡从单个查询中获得的结果。我没有测试此代码,请将其作为起点:

SET @rank1=0;
SET @rank2=0;
SET @rank3=0;
SELECT id, title, type, rank
FROM (
    (

    SELECT @rank1:=@rank1+1 AS rank, id, title, 'customer' AS type, MATCH (title) AGAINST ('+test* ' IN BOOLEAN MODE) AS score
    FROM customers
    WHERE MATCH (title) AGAINST ('+test* ' IN BOOLEAN MODE)
    )
    UNION DISTINCT
    (

    SELECT @rank2:=@rank2+1 AS rank, id, title, 'project' AS type, MATCH (title) AGAINST ('+test* ' IN BOOLEAN MODE) AS score
    FROM projects
    WHERE MATCH (title) AGAINST ('+test* ' IN BOOLEAN MODE)
    )
    UNION DISTINCT
    (

    SELECT @rank3:=@rank3+1 AS rank, id, title, 'task' AS type, MATCH (title) AGAINST ('+test* ' IN BOOLEAN MODE) AS score
    FROM tasks
    WHERE MATCH (title) AGAINST ('+test* ' IN BOOLEAN MODE)
    )
) res
ORDER BY rank 
LIMIT 6;

要使@kiks73在一个查询中产生结果而不声明@rankX变量,可以将SELECT@rankX:=0作为t添加到from子句中。像这样:

SELECT id, title, type, rank
FROM (
    (

    SELECT @rank1:=@rank1+1 AS rank, id, title, 'customer' AS type, MATCH (title) AGAINST ('+test* ' IN BOOLEAN MODE) AS score
    FROM customers,(SELECT @rank1:=0) AS t
    WHERE MATCH (title) AGAINST ('+test* ' IN BOOLEAN MODE)
    )
    UNION DISTINCT
    (

    SELECT @rank2:=@rank2+1 AS rank, id, title, 'project' AS type, MATCH (title) AGAINST ('+test* ' IN BOOLEAN MODE) AS score
    FROM projects,(SELECT @rank2:=0) AS t
    WHERE MATCH (title) AGAINST ('+test* ' IN BOOLEAN MODE)
    )
    UNION DISTINCT
    (

    SELECT @rank3:=@rank3+1 AS rank, id, title, 'task' AS type, MATCH (title) AGAINST ('+test* ' IN BOOLEAN MODE) AS score
    FROM tasks,(SELECT @rank3:=0) AS t
    WHERE MATCH (title) AGAINST ('+test* ' IN BOOLEAN MODE)
    )
) res
ORDER BY rank
LIMIT 6;

要使@kiks73在一个查询中产生结果而不声明@rankX变量,可以将SELECT@rankX:=0作为t添加到from子句中。像这样:

SELECT id, title, type, rank
FROM (
    (

    SELECT @rank1:=@rank1+1 AS rank, id, title, 'customer' AS type, MATCH (title) AGAINST ('+test* ' IN BOOLEAN MODE) AS score
    FROM customers,(SELECT @rank1:=0) AS t
    WHERE MATCH (title) AGAINST ('+test* ' IN BOOLEAN MODE)
    )
    UNION DISTINCT
    (

    SELECT @rank2:=@rank2+1 AS rank, id, title, 'project' AS type, MATCH (title) AGAINST ('+test* ' IN BOOLEAN MODE) AS score
    FROM projects,(SELECT @rank2:=0) AS t
    WHERE MATCH (title) AGAINST ('+test* ' IN BOOLEAN MODE)
    )
    UNION DISTINCT
    (

    SELECT @rank3:=@rank3+1 AS rank, id, title, 'task' AS type, MATCH (title) AGAINST ('+test* ' IN BOOLEAN MODE) AS score
    FROM tasks,(SELECT @rank3:=0) AS t
    WHERE MATCH (title) AGAINST ('+test* ' IN BOOLEAN MODE)
    )
) res
ORDER BY rank
LIMIT 6;

谢谢你的回答,但是MySQL似乎不允许我使用SET语法错误。你知道为什么吗?@DylanVB我已经编辑了答案:可能set声明语句应该在selects之外。在查询之外声明变量确实有效。有没有办法在查询中设置变量?@DylanVB是的,我在下一个回答中回答了。谢谢你的回答,但是MySQL似乎不允许我使用set语法错误。你知道为什么吗?@DylanVB我已经编辑了答案:可能set声明语句应该在selects之外。在查询之外声明变量确实有效。有没有办法在查询中设置变量?@DylanVB是的,我在下一个答案中回答了。