我有一张名称,组织者,得分1和得分2的表格。有效的初始部分是一个非常简单的查询。
查询1:
SELECT * FROM mvan m
WHERE m.score1 BETWEEN 30 and 80 AND m.score2 > 60;
基本上我只需要它,而且效果很好。但问题是我需要为每个组织者返回至少25行 - 而且该查询并不能让每个组织者获得25行。我可以将查询更改为以下内容,但问题是它不会被优化(因为很明显,score1中的NULL值不如那些不是NULL的值)。
查询2:
SELECT * FROM mvan m
WHERE (m.score1 BETWEEN 30 and 80 OR m.score1 IS NULL) AND m.score2 > 60;
如果每个组织者的行数是> = 25,有没有办法编写它将使用第一个查询的代码?如果< = 25则使用第二个查询25?
-
编辑:
这里是我得到的最接近的,但是它使用了我不想要的UNION ALL,因为它只会将两个查询混在一起。但我认为这给出了我想要的一般描述:
SELECT *
FROM mvan m
INNER JOIN
(SELECT organizer, count(*) As namecount
FROM mvan m
WHERE (m.score1 between 30 and 80 OR m.score1 IS NULL) AND m.score2 > 60)
GROUP BY organizer) t1
ON m.organizer = t1.organizer
WHERE t1.namecount < 25
UNION ALL
SELECT *
FROM mvan m
INNER JOIN
(SELECT organizer, count(*) As namecount
FROM mvan m
WHERE (m.score1 between 30 and 80) AND m.score2 > 60)
GROUP BY organizer) t2
ON m.organizer = t2.organizer
WHERE t2.namecount >= 25;
答案 0 :(得分:1)
使用PHP MySQLi(可能更好):
$connection = ...; #mysqli stuff
$query1 = ...;
$query2 = ...;
$result = $connection->query($query1);
if ($result->num_rows < 25) {
$result = $connection->query($query2);
}//if
纯SQL(这是低效的;你应该使用PHP或其他东西)。我不得不手动指定列名;您可以使用*
代替col1, col2, col3
,但如果您这样做,最终会出现“计数”列,这会导致结果混乱:
SELECT col1, col2, col3 FROM
(SELECT count(*) as count FROM (<query 1>) q11) a1
CROSS JOIN
(<query 1>) a2
WHERE a1.count >= 25
UNION ALL
SELECT col1, col2, col3 FROM
(SELECT count(*) as count FROM (<query 1>) q12) a3
CROSS JOIN
(<query 2>) a4
WHERE a3.count < 25;
或者,包括您的查询:
SELECT col1, col2, col3 FROM
(SELECT count(*) as count FROM (SELECT * FROM mvan m
WHERE t.score1 BETWEEN 30 and 80 AND m.score2 > 60;) q11) a1
CROSS JOIN
(SELECT * FROM mvan m
WHERE t.score1 BETWEEN 30 and 80 AND m.score2 > 60;) a2
WHERE a1.count >= 25
UNION ALL
SELECT col1, col2, col3 FROM
(SELECT count(*) as count FROM (<SELECT * FROM mvan m
WHERE t.score1 BETWEEN 30 and 80 AND m.score2 > 60;) q12) a3
CROSS JOIN
(SELECT * FROM mvan m
WHERE (t.score1 BETWEEN 30 and 80 OR t.score1 IS NULL) AND m.score2 > 60;) a4
WHERE a3.count < 25;
我还要指出,您的初始查询似乎无效;什么表有别名?
答案 1 :(得分:0)
如果您需要25行,请将order by
与limit
一起使用。只需确定所需行的优先级:
SELECT *
FROM mvan m
ORDER BY (t.score1 BETWEEN 30 and 80) DESC,
(m.score2 > 60) DESC
LIMIT 25;
这会优先考虑您想要的行,然后完成其余的工作。
编辑:
SELECT *
FROM mvan m
WHERE (t.score1 BETWEEN 30 and 80 AND t.score1 IS NULL) AND
(m.score2 > 60)
ORDER BY (CASE WHEN t.score1 BETWEEN 30 and 80 AND m.score2 > 60
THEN 1
WHEN t.score1 IS NULL ans m.score2 > 60
THEN 2
END)
LIMIT 25;
我错过了你问题的细微差别。如果未满足第一个条件,您需要score1
为NULL
的行。所以: