MySQL:如果然后查询语句基于如果分组具有少于特定数字

时间:2015-09-29 01:51:31

标签: mysql

我有一张名称,组织者,得分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;

2 个答案:

答案 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 bylimit一起使用。只需确定所需行的优先级:

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;

我错过了你问题的细微差别。如果未满足第一个条件,您需要score1NULL的行。所以: