2013-10-09 56 views
1

我有一个表由驱动程序记录硬件上发生的事件,当客户端应用程序正在执行一个特殊的过程(比如manteinance)时,在此操作过程中保存的事件是由用户而不是I/O(传感器和东西)来处理这个问题,因为我需要保存所有可能发生的事件(通过正常操作或用户操作发生)。 我需要能够过滤这些“维护模式”数据并获取自动生成的信息,为了做到这一点,我在由硬件填充的表中插入“START”和“END”行,我可以知道儿子何时非功能性数据开始,在哪里结束,这样的事情:MySQL SELECT不包括几个范围

id | fieldlist... 
---+-------------------- 
1 | event1 
2 | event2 
3 | event3 
4 | manteinance start (inserted by me) 
5 | event_by_technician1 
6 | event_by_technician2 
7 | event_by_technician3 
8 | manteinance finish (inserted by me) 
9 | event4 
10| event5 
11| manteinance start (inserted by me) 
12| event_by_technicianx 
13| event_by_techniciany 
14| manteinance finish (inserted by me) 
15| eventA 
16| manteinance start (inserted by me) 
17| event_by_technician 
18| manteinance finish (inserted by me) 
19| many many more records and start/finish pairs... 

我需要过滤所有这些event_by_technician *并获得唯一的事件*行,有没有一种方法来查询的信息清洁容易,对于变量和非统一的范围集?

感谢

编辑:我想我没有说清楚,还有服务器上运行两个应用程序,我的基于PHP的Web应用程序和外部的驱动程序。这两个脚本/应用程序访问相同的数据库,驱动程序插入传感器和其他硬件状态的数据,Web应用程序读取并显示一些相当不错的图形(它在用户请求上插入'信号'行,即单击按钮)。通过比较来判断一个事件是来自于manteinance还是正常的操作是不可能的,因为它们是一样的,区分它们的原因是技术人员点击网页上的按钮启动,而另一个则完成。 我需要的是询问Mysql:“嘿,给我一行不在field1 = 1(start)的行和另一个field1 = 2(end)之间的行。考虑到沿着结果。

我想我正在重构表用php把一个额外的列开始/结束行周围的结果集循环之间的数据的方式。然后让我querys。

+4

不要这样做,它会使过滤h arder。添加一列,默认为false,称为'maintenance_event',并在所有维护事件中将其设置为true。然后过滤是微不足道的。 –

+0

那么,你的预期输出是什么? –

+0

问题是我不插入数据,一个单独的驱动程序正在运行插入数据而不知道事件是由于mainteinance还是一个可操作的事件导致的,我(php)只是知道用户何时启动应用程序,她的手在硬件上,当完成(通过结束对应用程序的操作),这就是为什么我试图这样。我的其他方法是用php重复结果并反复重新格式化数据(例如设置一个像你这样的字段),但这似乎有点混乱。 – Anfelipe

回答

0

你可以使用LIKE和'?'更换一个字符,例如:。

SELECT * FROM table WHERE fieldlist LIKE 'event?' 
+0

这也会返回'eventA',而OP似乎并没有预料到 –

+0

使用event1,event2,eventA,eventZ,event99999是任意显示的,这是正常操作引起的事件,而event_by_technitian是由操纵,但两者在结构和形式上都是平等的,你只是无法分辨某个记录是否是由某一个或另一个造成的,而只能用开始和结束的时间戳。它们不是litterally字符串,所以LIKE不适用于这个目的。感谢您的回答 – Anfelipe

0

使用用户定义的函数应该是最有效的方法你可以去这样的:

SELECT id, event FROM (
    SELECT id, event, 
     @manteinance := (@manteinance_started OR @manteinance) AND event != 'manteinance finish' m, 
     @manteinance_started := event = 'manteinance start' ms 
    FROM t, (SELECT @manteinance := FALSE, @manteinance_started := FALSE) init 
    HAVING m = 0 
    ORDER BY id 
) s 
WHERE event NOT IN ('manteinance start', 'manteinance finish') 

输出:

| ID |           EVENT | 
|----|--------------------------------------------------| 
| 1 |           event1 | 
| 2 |           event2 | 
| 3 |           event3 | 
| 9 |           event4 | 
| 10 |           event5 | 
| 15 |           eventA | 
| 19 | many many more records and start/finish pairs... | 

小提琴here