Informix - 从表中获取记录

时间:2010-05-27 11:48:24

标签: informix

考虑下表:

Col1 Col2 Col3

123  ABC  20/5/2010
123  CDS  21/5/2010
123  VDS  22/5/2010
123  ABC  23/5/2010
123  VDS  24/5/2010
123  CDS  25/5/2010
123  ABC  26/5/2010

我需要获取第一次出现的CDS并计算下一行之间的时间差异。 同样,我需要找出下一次出现的CDS并计算下一行的时间差异。 这必须继续,直到表中没有出现CDS为止。

如果有人可以提供帮助,将不胜感激!

3 个答案:

答案 0 :(得分:1)

您想要的输出是多少?它是这样的:

123 ABC 20/5/2010 
123 CDS 21/5/2010 
123 VDS 22/5/2010 1 day, 0:00:00
123 ABC 23/5/2010 
123 VDS 24/5/2010 
123 CDS 25/5/2010 
123 ABC 26/5/2010 1 day, 0:00:00

如果是这样,那么我认为最简单的方法是:用Python或类似语言创建程序,使用SQL选择数据并使用您选择的语言计算日期差异。在“普通”SQL中没有像“下一行”这样的东西,在其他语言中你可以保存最后一个CDS的日期并在下一个循环迭代中使用它。

此输出是使用Python创建的:

import time
import datetime

TXT = """123 ABC 20/5/2010
123 CDS 21/5/2010
123 VDS 22/5/2010
123 ABC 23/5/2010
123 VDS 24/5/2010
123 CDS 25/5/2010
123 ABC 26/5/2010"""

def txt2time(ts):
    tpl = time.strptime(ts, '%d/%m/%Y')
    return time.mktime(tpl) 

last_date = ''
for line in TXT.split('\n'):
    date_diff = ''
    arr = line.split()
    if last_date:
        date_diff = '%s' % (datetime.timedelta(seconds = (txt2time(arr[2]) - txt2time(last_date))))
        last_date = ''
    if arr[1] == 'CDS':
        last_date = arr[2]
    print('%s %s' % (line.strip(), date_diff))

如您所见,我遍历文本行,但您可以轻松地使用split('\n')更改第一个循环以循环记录集:

for row in cursor.fetchall():
  if row[0] == 'CDS':
      ...

(您可以在许多网页上找到Python / Jython示例,包括我在SO上的问题和答案)。

我认为只能在SQL中找到这样的解决方案。您将需要从下一行返回日期的函数。而且我认为创建这样的函数可能并不容易,因为这样的函数必须像过滤和排序的select一样。

答案 1 :(得分:0)

对于样本数据,在Col2中只有一对值为CDS的行,因此输出中只有一行。如果有4行CDS,你不清楚你会期望什么。您的措辞可能意在暗示第一对将贡献一行而第二对将贡献第二行。或者可能是您需要找到连续出现的CDS之间的差异,以便4行数据将产生3行输出。 (这个问题也让人们可以讨论这是否适用于Col1的单个值,或者Col1对结果是否无关紧要。)

由于存在歧义,我将解决第二个选项,假设CDS条目都必须在Col1中具有相同的值(但Col1中可能有许多不同的值)。

您没有提到您拥有的Informix版本;我假设IDS 11.50。语法可能在早期版本中不起作用。

通常情况下,该表在问题中是匿名的 - 因此在此指定为Tab1。

查询

SELECT t1a.col1, t1a.col2, t1a.col3, t1b.col3 AS col4,
       t1b.col3 - t1a.col3 AS delta
  FROM tab1 AS t1a JOIN tab1 AS t1b
    ON t1a.col1 = t1b.col1 AND
       t1a.col3 < t1b.col3 AND
       t1a.col2 = t1b.col2 AND
       t1a.col2 = 'CDS'    AND
       NOT EXISTS(SELECT *
                    FROM tab1 AS t1c
                   WHERE t1c.col3 > t1a.col3 AND
                         t1c.col3 < t1b.col3 AND
                         t1c.col1 = t1a.col1 AND
                         t1c.col2 = t1a.col2
                  );

'&lt;'连接订单日期,使't1a'值小于't1b'值; NOT EXISTS子句通过断言tab1中没有与col1和col2相同的值以及在较早日期之后和之后日期之前的日期来确保它们彼此相邻。这是查询的关键部分。

结果

   col1     col2     col3            col4            delta
   123      CDS      21/05/2010      25/05/2010      4
   123      CDS      14/04/2010      22/04/2010      8
   123      CDS      22/04/2010      21/05/2010      29
   120      CDS      11/05/2010      16/05/2010      5
   121      CDS      21/04/2010      30/04/2010      9

模式

CREATE TABLE tab1 (col1 SMALLINT, col2 CHAR(3), col3 DATE);

数据

使用DBDATE = DMY4 /.

运行
INSERT INTO tab1(col1, col2, col3) VALUES (123, 'ABC', '20/5/2010');
INSERT INTO tab1(col1, col2, col3) VALUES (123, 'CDS', '21/5/2010');
INSERT INTO tab1(col1, col2, col3) VALUES (123, 'VDS', '22/5/2010');
INSERT INTO tab1(col1, col2, col3) VALUES (123, 'ABC', '23/5/2010');
INSERT INTO tab1(col1, col2, col3) VALUES (123, 'VDS', '24/5/2010');
INSERT INTO tab1(col1, col2, col3) VALUES (123, 'CDS', '25/5/2010');
INSERT INTO tab1(col1, col2, col3) VALUES (123, 'ABC', '26/5/2010');
INSERT INTO tab1(col1, col2, col3) VALUES (123, 'ABC', '10/4/2010');
INSERT INTO tab1(col1, col2, col3) VALUES (123, 'CDS', '14/4/2010');
INSERT INTO tab1(col1, col2, col3) VALUES (123, 'VDS', '12/4/2010');
INSERT INTO tab1(col1, col2, col3) VALUES (123, 'ABC', '13/4/2010');
INSERT INTO tab1(col1, col2, col3) VALUES (123, 'VDS', '19/4/2010');
INSERT INTO tab1(col1, col2, col3) VALUES (123, 'CDS', '22/4/2010');
INSERT INTO tab1(col1, col2, col3) VALUES (123, 'ABC', '16/4/2010');
INSERT INTO tab1(col1, col2, col3) VALUES (120, 'ABC', '10/5/2010');
INSERT INTO tab1(col1, col2, col3) VALUES (120, 'CDS', '11/5/2010');
INSERT INTO tab1(col1, col2, col3) VALUES (120, 'VDS', '12/5/2010');
INSERT INTO tab1(col1, col2, col3) VALUES (120, 'ABC', '13/5/2010');
INSERT INTO tab1(col1, col2, col3) VALUES (120, 'VDS', '14/5/2010');
INSERT INTO tab1(col1, col2, col3) VALUES (120, 'CDS', '16/5/2010');
INSERT INTO tab1(col1, col2, col3) VALUES (121, 'ABC', '17/5/2010');
INSERT INTO tab1(col1, col2, col3) VALUES (121, 'CDS', '21/4/2010');
INSERT INTO tab1(col1, col2, col3) VALUES (121, 'ABC', '22/4/2010');
INSERT INTO tab1(col1, col2, col3) VALUES (121, 'VDS', '23/4/2010');
INSERT INTO tab1(col1, col2, col3) VALUES (121, 'ABC', '24/4/2010');
INSERT INTO tab1(col1, col2, col3) VALUES (121, 'VDS', '25/4/2010');
INSERT INTO tab1(col1, col2, col3) VALUES (121, 'ABC', '26/4/2010');
INSERT INTO tab1(col1, col2, col3) VALUES (121, 'ABC', '27/4/2010');
INSERT INTO tab1(col1, col2, col3) VALUES (121, 'ABC', '28/4/2010');
INSERT INTO tab1(col1, col2, col3) VALUES (121, 'ABC', '29/4/2010');
INSERT INTO tab1(col1, col2, col3) VALUES (121, 'CDS', '30/4/2010');
INSERT INTO tab1(col1, col2, col3) VALUES (122, 'ABC', '23/4/2010');
INSERT INTO tab1(col1, col2, col3) VALUES (122, 'VDS', '24/4/2010');
INSERT INTO tab1(col1, col2, col3) VALUES (122, 'CDS', '25/4/2010');
INSERT INTO tab1(col1, col2, col3) VALUES (122, 'ABC', '26/4/2010');

答案 2 :(得分:0)

要么我不明白什么似乎是一个简单的问题或其他人都在思考它。

SELECT col1, col2, col3, 
(SELECT MIN(a.col3) FROM tab1 a WHERE a.col3 > z.col3) - z.col3 AS DaysDiff
FROM tab1 z
WHERE z.col2 = "CDS"