0

次の構造のSybaseSQLAnywhereデータベースにテーブルがあります(必須ではないフィールドは削除されています)。このテーブルには、営業日の間に開閉する小売店のレジスタが入力されます。何日もの履歴がテーブルに保持され、その日の開始時にレジスタのステータスは閉じられていると見なされます。「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を超えています。抽出しようとしているデータは、1日あたりの同時オープンレジスタの最大数、つまり次のようなテーブルです。

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

これは、かなり基本的なSybase SQLだけで行うことができますか?つまり、集計関数 "WITH 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 に答える