6

使用したテーブル:

1) v(日付 d、名前 c(25)、説明 c(50)、借方 n(7)、貸方 n(7))

'v' の名前は、vn テーブルの名前を参照します

2) vn(日付 d、名前 c(25)、タイプ c(25)、obal n(7))

「vn」の名前は主キーであり、さまざまな名前がタイプ別にグループ化されています

例: 名前 abc、def、ghi はタイプ 'bank' に属し、名前 xyz、pqr はタイプ 'ledger' に属します...

次のようなクエリがあります。

SELECT vn.type, SUM(vn.obal + IIF(v.date < sd, v.credit-v.debit, 0)) OpBal, ;
    SUM(IIF(BETWEEN(v.date, sd, ed), v.credit-v.debit, 0)) CurBal ;
    FROM v, vn WHERE v.name = vn.name GROUP BY vn.type ;
    ORDER BY vn.type HAVING OpBal + CurBal != 0

それは正常に動作しますが、唯一の問題は、obal はテーブル 'vn' の名前ごとに 1 回だけ入力される値ですが、テーブル 'v' の貸方と借方の計算ごとにこのクエリを使用すると、obal が複数回追加され、下に表示されることです。 OpBal。クエリが次のように変更された場合:

SELECT vn.type, vn.obal + SUM(IIF(v.date < sd, v.credit-v.debit, 0)) OpBal, ;
    SUM(IIF(BETWEEN(v.date, sd, ed), v.credit-v.debit, 0)) CurBal ;
    FROM v, vn WHERE v.name = vn.name GROUP BY vn.type ;
    ORDER BY vn.type HAVING OpBal + CurBal != 0

「Group by 句が見つからないか無効です」のようなエラー メッセージが表示されます。

RDBMS は MS Visual Foxpro 9 を使用しました。sd と ed は、sd < ed のクエリの目的で使用される日付型変数です。

期待される結果を得るために私を助けてください。どうもありがとう。

4

3 に答える 3

0

ほんの少しのこと。VFP 9には、下位互換性のためにすべての非集計のグループ化を必要としない設定があり、すべての列が集計である必要がないMySQLのような同様の結果があります。PK列で結合しているレコードの数(名前、住所、電話番号など)に関係なく変更されない、顧客のレコードからの追加の列のクエリなど。

SET ENGINEBEHAVIOR 80

VFP9のデフォルト

SET ENGINEBEHAVIOR 90

準拠するには、group-by以外のすべての列が集計である必要があります。

次に...処理しているテーブルに非常に悪い列があるようです...VFPの3つの予約語..."date"、 "Name"、 "type"ですが、これらを修飾することで問題ありません。 alias.column参照を使用したクエリ。

次のサンプルコードは、質問で説明した構造の一時テーブル(カーソル)を作成します。また、いくつかのサンプルデータを挿入し、「sd」(開始日)変数と「ed」(終了日)変数をシミュレートしました

CREATE CURSOR vn;
   ( date d, ;
     name c(25), ;
     type c(25), ;
     obal n(7) )

INSERT INTO vn VALUES ( CTOD( "5/20/2012" ), "person 1", "person type 1", 125 )
INSERT INTO vn VALUES ( CTOD( "5/20/2012" ), "person 2", "another type ", 2155 )

CREATE CURSOR v;
   ( date d, ;
     name c(25), ;
     desc c(50), ;
     debit n(7), ;
     credit n(7))

INSERT INTO V VALUES ( CTOD( "6/1/2012" ), "person 1", "description 1", 10, 32 )
INSERT INTO V VALUES ( CTOD( "6/2/2012" ), "person 1", "desc 2", 235, 123 )
INSERT INTO V VALUES ( CTOD( "6/3/2012" ), "person 1", "desc 3", 22, 4 )
INSERT INTO V VALUES ( CTOD( "6/4/2012" ), "person 1", "desc 4", 53, 36 )
INSERT INTO V VALUES ( CTOD( "6/5/2012" ), "person 1", "desc 5", 31, 3 )
INSERT INTO V VALUES ( CTOD( "6/1/2012" ), "person 2", "another 1", 43, 664 )
INSERT INTO V VALUES ( CTOD( "6/4/2012" ), "person 2", "more desc", 78, 332 )
INSERT INTO V VALUES ( CTOD( "6/6/2012" ), "person 2", "anything", 366, 854 )

sd = CTOD( "6/3/2012" )      && start date of transactions
ed = DATE()  && current date as the end date...

さて、クエリを実行しています...タイプ別にグループを取得しようとしていますが、最初に1人あたり(名前)を1人あたりに事前に集計する必要があります。ここで、特定の時点での基準として開始日(sd)より前のトランザクションの合計開始残高を取得しようとしているようです。次に、問題の開始日/終了日内のアクティビティを確認します。最初にこれを行いますが、「vn」テーブルから「obal」列を追加することは扱いません。group by以外の列の集計が必要なため、列の「MAX()」を使用します。これはPK(名前)ベースであるため、最終的にはそれが何であれ、トランザクションの合計がロールアップされますが、すべてのデータは...を介して単一の行に事前に要約されます。

select;
      vn.name,;
      vn.type,;
      MAX( vn.obal ) as BalByNameOnly,;
      SUM( IIF( v.date < sd, v.credit-v.debit, 000000.00 )) OpBal, ;
      SUM( IIF( BETWEEN(v.date, sd, ed), v.credit - v.debit, 000000.00 )) CurBal ;
   FROM ;
      v,;
      vn ;
   WHERE ;
      v.name = vn.name;
   GROUP BY ;
      vn.Name,;
      vn.Type;
   INTO ;
      CURSOR C_JustByName READWRITE 

この結果(私のサンプルデータから)は次のようになります...

Name      Type            BalByNameOnly   OpBal   CurBal
person 1  person type 1       125         -90     -63 
person 2  another type       2155         621     742

タイプ別に取得する最終的な集計では、上記の結果「カーソル」(C_JustByName)をクエリし、ITを使用して、タイプ、所有などでグループ化を取得できます。

SELECT ;
      JBN.type, ;
      JBN.BalByNameOnly - JBN.OpBal as OpBal,;
      JBN.CurBal ;
    FROM ;
       C_JustByName JBN ;
    GROUP BY ;
       vn.type ;
    ORDER BY ;
       vn.type ;
    HAVING ;
       OpBal + CurBal != 0;
    INTO ;
       CURSOR C_Final

目的とoBal列が不明な日付の「VN」(顧客テーブルのように見える)内の日付として、あなたが実際に何を探しているのかわからないため、上記を単純化しています。トランザクションテーブルに関して。

VFPの良いところは、永続テーブルを作成せずに一時カーソルにクエリを実行し、その後のクエリの基礎としてITを使用できることです...クエリ内のクエリ内にクエリをネストする必要がないという読みやすさの助けになります。また、各レイヤーの結果を確認し、次のクエリフェーズに進む前に、期待する答えが得られていることを確認できます...

うまくいけば、これはあなたが解決しようとしていることの方向にあなたを助けるでしょう。

于 2012-07-14T02:10:17.167 に答える
0

数分前に初めて VFP を使用した SQL の SQL 構文を見たので、これはエラーでいっぱいになる可能性がありますが、「推測」としては次のとおりです。

SELECT vn.type, 
       SUM(vn.obal + (SELECT SUM(IIF(v.date < sd, v.credit-v.debit, 0)) 
                      FROM v 
                      WHERE v.name = vn.name)) OpBal,
       SUM(SELECT SUM(IIF(BETWEEN(v.date, sd, ed), v.credit-v.debit, 0))
           FROM v 
           WHERE v.name = vn.name) CurBal
FROM vn
GROUP BY vn.type
ORDER BY vn.type 
HAVING OpBal + CurBal != 0

基本的に、 vn.obal が繰り返されるのを避けるために、 v からの選択をサブセレクトに変えました。すべてを合計する前に、最初に個々の人の合計を取得することは v にとって重要ではありません。

于 2012-07-07T12:27:46.567 に答える