简体   繁体   English

MySQL在按条件分组的多列时选择行

[英]MySQL Selecting rows while grouping by multiple columns with a condition

I have a table of events.我有一个事件表。 A host can create multiple events on a single day.主持人可以在一天内创建多个事件。 Some of the events are recurring and some are not.有些事件会重复发生,有些则不会。 I have a complex (for me) SELECT statement that I think requires conditionals some how and perhaps a subquery and I don't really know how to approach it.我有一个复杂的(对我来说) SELECT 语句,我认为它需要一些条件,也许是一个子查询,但我真的不知道如何处理它。

Select Priority:选择优先级:

  1. If a host has more then one event on the same date and one of those dates is not recurring (0) then only select the non-recurring event for that host on that date.如果主持人在同一日期有多个事件,并且其中一个日期不重复 (0),则仅选择该主持人在该日期的非重复事件。
  2. If a host has more then one event on the same date and all of the events on that date are recurring then select all events for that host on that date.如果主持人在同一日期有多个事件,并且该日期的所有事件都重复发生,则选择该主持人在该日期的所有事件。
  3. If a host only has one event on a given date select it regardless of whether it is recurring or not.如果主持人在给定日期只有一个事件,则无论它是否重复都选择它。

Here is a sample Events table:这是一个示例事件表:

+----+--------+---------+------------+-----------+
| id | hostid |  title  | start_date | recurring |
+----+--------+---------+------------+-----------+
|  1 |      1 | Event1A | 2016-10-01 |         1 |
|  2 |      1 | Event1B | 2016-10-01 |         0 |
|  3 |      1 | Event1C | 2016-10-02 |         0 |
|  4 |      1 | Event1D | 2016-10-02 |         1 |
|  5 |      1 | Event1E | 2016-10-02 |         1 |
|  6 |      1 | Event1F | 2016-10-03 |         1 |
|  7 |      1 | Event1G | 2016-10-03 |         1 |
|  8 |      1 | Event1H | 2016-10-04 |         1 |
|  9 |      1 | Event1I | 2016-10-05 |         0 |
| 10 |      2 | Event2A | 2016-10-01 |         1 |
| 11 |      2 | Event2B | 2016-10-01 |         0 |
| 12 |      2 | Event2C | 2016-10-02 |         1 |
| 13 |      2 | Event2D | 2016-10-03 |         0 |
+----+--------+---------+------------+-----------+

Here are my desired Results:这是我想要的结果:

+----+--------+---------+------------+-----------+
| id | hostid |  title  | start_date | recurring |
+----+--------+---------+------------+-----------+
|  2 |      1 | Event1B | 2016-10-01 |         0 |
|  3 |      1 | Event1C | 2016-10-02 |         0 |
|  6 |      1 | Event1F | 2016-10-03 |         1 |
|  7 |      1 | Event1G | 2016-10-03 |         1 |
|  8 |      1 | Event1H | 2016-10-04 |         1 |
|  9 |      1 | Event1I | 2016-10-05 |         0 |
| 11 |      2 | Event2B | 2016-10-01 |         0 |
| 12 |      2 | Event2C | 2016-10-02 |         1 |
| 13 |      2 | Event2D | 2016-10-03 |         0 |
+----+--------+---------+------------+-----------+

Here is a SQL Fiddle link with the table:这是带有该表的 SQL Fiddle 链接:

http://sqlfiddle.com/#!9/6427e/6 http://sqlfiddle.com/#!9/6427e/6

The task is rather simple: You want the record(s) with the minimum recurring flag per host and date.任务相当简单:您需要每个主机和日期具有最少重复标记的记录。

select events.*
from
(
  select hostid, start_date, min(recurring) as recurring
  from events
  group by hostid, start_date
) chosen
join events on events.hostid = chosen.hostid
            and events.start_date = chosen.start_date
            and events.recurring = chosen.recurring
order by events.id;

Here is your SQL fiddle back: http://sqlfiddle.com/#!9/6427e/59 :-)这是你的 SQL 小提琴: http : //sqlfiddle.com/#!9/ 6427e/59 :-)

A friend helped me find this solution:一个朋友帮我找到了这个解决方案:

SELECT e.* 
FROM Events e 
LEFT JOIN (
    SELECT start_date,
    hostid,
    count(*) cnt,
    AVG(Cast(recurring as decimal)) recur
    FROM Events
    GROUP BY start_date, hostid
) r
ON e.start_date = r.start_date 
AND e.hostid = r.hostid
WHERE (e.recurring = 0 and r.recur <> 1)
OR r.recur = 1 OR r.cnt = 1
ORDER BY e.id

http://sqlfiddle.com/#!9/6427e/65 http://sqlfiddle.com/#!9/6427e/65

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM