0

我在 Sybase SQL Anywhere 数据库中有一个表,该表具有以下结构(已删除非必要字段),该表由在工作日期间打开和关闭的零售商店寄存器填充。许多天的历史记录都保存在表中,并且在一天开始时,寄存器的状态被假定为关闭。“OPENTILL”表示打开业务登记簿,“CLOSETILL”表示关闭它:

Register   Transaction_Date      Transaction_Time     Transaction_Type
1          2013-02-25            08:00:00.000         OPENTILL
2          2013-02-25            08:01:00.000         OPENTILL
3          2013-02-25            08:02:00.000         OPENTILL
2          2013-02-25            09:00:00.000         CLOSETILL
3          2013-02-25            09:01:00.000         CLOSETILL
2          2013-02-25            10:00:00.000         OPENTILL
4          2013-02-25            11:00:00.000         OPENTILL
3          2013-02-25            12:00:00.000         OPENTILL
2          2013-02-25            13:00:00.000         CLOSETILL
1          2013-02-25            14:00:00.000         CLOSETILL
3          2013-02-25            15:00:00.000         CLOSETILL
4          2013-02-25            20:00:00.000         CLOSETILL

这只是样本数据,实际寄存器数量超过 4 个。我要提取的数据是每天同时打开的寄存器的最大数量,即这样的表:

Date             Max_Concurrent_Registers
2013-02-25       14
2013-02-24       9
2013-02-23       12
2013-02-22       8

仅使用相当基本的 Sybase SQL 就可以做到这一点——即聚合函数、“WIT​​H x AS (...)”、子选择,但没有游标或存储过程?

感谢您的任何帮助

4

2 回答 2

3

有趣的是,前几天参与了一个类似问题的讨论:)

SELECT transaction_date, MAX(concurrent_count)
  FROM ( SELECT transaction_date, Transaction_Time, Transaction_Type
               ,SUM( CASE WHEN transaction_type = 'OPENTILL' THEN 1 ELSE -1 END )
                OVER( PARTITION BY transaction_date
                      ORDER BY Transaction_Time ) AS concurrent_count
           FROM myTable
       ) x
   GROUP BY transaction_date

在 Postgres 中运行的示例:

postgres=# SELECT transaction_date, Transaction_Time, Transaction_Type
postgres-#                ,SUM( CASE WHEN transaction_type = 'OPENTILL' THEN 1 ELSE -1 END )
postgres-#                 OVER( PARTITION BY transaction_date ORDER BY Transaction_Time ) AS concurrent_count
postgres-#            FROM myTable;
 transaction_date | transaction_time | transaction_type | concurrent_count
------------------+------------------+------------------+------------------
 2013-02-25       | 08:00:00         | OPENTILL         |                1
 2013-02-25       | 08:01:00         | OPENTILL         |                2
 2013-02-25       | 08:02:00         | OPENTILL         |                3
 2013-02-25       | 09:00:00         | CLOSETILL        |                2
 2013-02-25       | 09:01:00         | CLOSETILL        |                1
 2013-02-25       | 10:00:00         | OPENTILL         |                2
 2013-02-25       | 11:00:00         | OPENTILL         |                3
 2013-02-25       | 12:00:00         | OPENTILL         |                4
 2013-02-25       | 13:00:00         | CLOSETILL        |                3
 2013-02-25       | 14:00:00         | CLOSETILL        |                2
 2013-02-25       | 15:00:00         | CLOSETILL        |                1
 2013-02-25       | 20:00:00         | CLOSETILL        |                0
(12 rows)


postgres=# SELECT transaction_date, MAX(concurrent_count)
postgres-#   FROM ( SELECT transaction_date, Transaction_Time, Transaction_Type
postgres(#                ,SUM( CASE WHEN transaction_type = 'OPENTILL' THEN 1 ELSE -1 END )
postgres(#                 OVER( PARTITION BY transaction_date ORDER BY Transaction_Time ) AS concurrent_count
postgres(#            FROM myTable
postgres(#        ) x
postgres-#    GROUP BY transaction_date;
 transaction_date | max
------------------+-----
 2013-02-25       |   4
(1 row)
于 2013-02-26T02:45:00.147 回答
1

最佳解决方案涉及累积和,但 Sybase 不支持这些。

您可以对相关子查询执行等效操作。其基本思想是,任何时候的开放收银台数量是开放收银台数量之和减去关闭收银台数量之和。最后一步就是找到最大值:

select transaction_date, max(opentills)
from (select t.*,
             (select (sum(case when transaction_type = 'opentill' then 1 else 0 end) -
                      sum(case when transaction_type = 'closetill' then 1 else 0 end)
                     ) as NetOPens
              from transactions t2
              where t.transaction_date = t2.transaction_date
                    t2.transaction_time <= t.transaction_time
             ) as OpenTills
      from transactions t
    ) t
group by transaction_date
order by 1
于 2013-02-26T03:00:53.377 回答