一些背景知识。我正在使用Rails 3进行拼车应用程序。我正在使用fullcalendar作为jquery日历库。当特定日期有很多事件时,它也不能很好地工作 。所以,我想要做的是拥有两个“事件源”。在一个中,我想返回按日期和类别分组的所有事件,这些事件的计数小于某个值。 对于其他人,我想要返回所有记录 more 而不是值的记录。
道歉如果不清楚,一些样本数据可能会使其更加明显
基本记录结构:
| id | date | category_id |
| 1 | 1-Aug | 1 |
| 2 | 1-Aug | 1 |
| 3 | 1-Aug | 1 |
| 4 | 1-Aug | 2 |
| 5 | 1-Aug | 2 |
| 6 | 1-Aug | 3 |
假设3是魔法计数(3或更高应该分组)我想要一个选择返回
| id | date | category_id | count |
| 1 | 1-Aug | 1 | 3 |
(我实际上并不关心ID可以使用group_concat组合(使用MYSQL),在我的用例中它并不重要 - 我想知道的是,8月1日类别1有3个条目
第二个选择应该返回其他所有内容
| id | date | category_id | count |
| 4 | 1-Aug | 2 | 2 |
| 5 | 1-Aug | 2 | 2 |
| 6 | 1-Aug | 3 | 1 |
我真的不需要返回计数,但重点是每个结果都有单独的行,没有计数> = 3.
目前我的SQL看起来像这样:
SELECT `pools`.*
FROM `pools`
INNER JOIN `fields` ON `fields`.`id` = `pools`.`field_id`
INNER JOIN `regions` ON `regions`.`id` = `fields`.`region_id`
INNER JOIN `countries` ON `countries`.`id` = `regions`.`country_id`
WHERE `regions`.`country_id` = 1
AND `pools`.`confirmed` = 1
AND (leaving_date >= '2012-04-30 00:00:00')
AND (leaving_date <= '2012-06-04 00:00:00')
GROUP BY field_id, leaving_date
HAVING count(*) >= 3
ORDER BY leaving_date
我可以遍历返回的数组 - 但如果可能的话,我宁愿做SQL方面。还想在最少数量的数据库之旅中做到这一点。一般指针真的很感激!
答案 0 :(得分:0)
这可能对开始有用:
CREATE TEMPORARY TABLE grouped_rows AS
SELECT `pools`.*
FROM `pools`
INNER JOIN `fields` ON `fields`.`id` = `pools`.`field_id`
INNER JOIN `regions` ON `regions`.`id` = `fields`.`region_id`
INNER JOIN `countries` ON `countries`.`id` = `regions`.`country_id`
WHERE `regions`.`country_id` = 1
AND `pools`.`confirmed` = 1
AND (leaving_date >= '2012-04-30 00:00:00')
AND (leaving_date <= '2012-06-04 00:00:00')
GROUP BY field_id, leaving_date;
HAVING count(*) >= 3;
SELECT `pools`.*
FROM `pools`
INNER JOIN `fields` ON `fields`.`id` = `pools`.`field_id`
INNER JOIN `regions` ON `regions`.`id` = `fields`.`region_id`
INNER JOIN `countries` ON `countries`.`id` = `regions`.`country_id`
LEFT JOIN grouped_rows ON grouped_rows.field_id = pools.field_id
AND grouped_rows.leaving_date = pools.leaving_date
WHERE `regions`.`country_id` = 1
AND `pools`.`confirmed` = 1
AND (leaving_date >= '2012-04-30 00:00:00')
AND (leaving_date <= '2012-06-04 00:00:00')
AND grouped_rows.some_not_null_field IS NULL
UNION ALL
SELECT * FROM grouped_rows
ORDER BY leaving_date;
DROP TEMPORARY TABLE grouped_rows;
我不知道您是否可以发出所有三个语句并在一次往返中获得UNION
的结果。
也许你可以将temptable的select选择嵌入到UNION
的两半中,但是它可能会给MySQL服务器带来更多的工作(或者没有)。
<强>更新强>
我找到了一个可以使用的单查询解决方案。这只是基本的骨架结构,但我认为你可以根据它转换你的查询:
http://sqlfiddle.com/#!2/f67e3/18
SELECT
IF( grouped.gcat, NULL, item.id ) AS out_id
,item.cat AS out_cat
,COALESCE( grouped.gcount, 1 ) out_count
FROM item
LEFT JOIN
(
SELECT count(*) AS gcount, cat AS gcat
FROM item
GROUP BY gcat
HAVING count(*) >= 3
) AS grouped
ON item.cat = grouped.gcat
GROUP BY out_id