MySQL - SELECT UNION 中的每个数量与总 LIMIT 的数量相等
MySQL - SELECT equal amount of each in UNION by total LIMIT
在 MySQL 数据库中,我有 3 个 table:customers
、projects
和 tasks
。对于我正在实施的搜索,我想搜索所有 3 个 table 和 select 找到的匹配项。问题是我想同样限制 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) 如果所有 table 至少有 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) 如果一个 table 没有任何结果,则为其他 2 个 table 中的每一个显示 3 个结果。 (如果只有一个 table 有结果,则显示 table 的 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) 如果 table 中的 2 个有超过 2 个结果,而第三个 table 只有 1 个结果,则显示 table 之一的 3 个结果足够的结果,两个中的另一个有 2 个结果,table 有 1 个结果,只有 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'
谁能帮我解决这个问题?
提前致谢!
您可以为每个 SELECT
使用一个行号,然后使用该计算字段对 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;
要在不声明@rankX 变量的情况下使@kiks73 在一个查询中产生结果,您可以在 from 子句中添加 (SELECT @rankX:=0) AS t
。像这样:
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 数据库中,我有 3 个 table:customers
、projects
和 tasks
。对于我正在实施的搜索,我想搜索所有 3 个 table 和 select 找到的匹配项。问题是我想同样限制 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) 如果所有 table 至少有 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) 如果一个 table 没有任何结果,则为其他 2 个 table 中的每一个显示 3 个结果。 (如果只有一个 table 有结果,则显示 table 的 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) 如果 table 中的 2 个有超过 2 个结果,而第三个 table 只有 1 个结果,则显示 table 之一的 3 个结果足够的结果,两个中的另一个有 2 个结果,table 有 1 个结果,只有 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'
谁能帮我解决这个问题?
提前致谢!
您可以为每个 SELECT
使用一个行号,然后使用该计算字段对 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;
要在不声明@rankX 变量的情况下使@kiks73 在一个查询中产生结果,您可以在 from 子句中添加 (SELECT @rankX:=0) AS t
。像这样:
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;