سؤال

لدي جدول مثل هذا (Oracle، 10)

Account     Bookdate     Amount
      1     20080101        100
      1     20080102        101
      2     20080102        200
      1     20080103       -200
...

ما أحتاج إليه هو جدول جديد مجمع حسب ترتيب الحساب حسب تصاعدي للحساب وتاريخ الحجز تصاعدي مع حقل إجمالي قيد التشغيل، مثل هذا:

Account     Bookdate     Amount     Running_total
      1     20080101        100               100
      1     20080102        101               201
      1     20080103       -200                 1
      2     20080102        200               200
...

هل هناك طريقة بسيطة للقيام بذلك؟

شكرا لك مقدما.

هل كانت مفيدة؟

المحلول

هل حقا بحاجة الى طاولة اضافية؟

ويمكنك الحصول على هذه البيانات التي تحتاج إليها مع استعلام بسيط، والتي يمكن أن تخلق من الواضح كطريقة عرض إذا كنت تريد أن تبدو وكأنها الجدول.

وهذا سوف تحصل على البيانات التي تبحث عن:

select 
    account, bookdate, amount, 
    sum(amount) over (partition by account order by bookdate) running_total
from t
/

وهذا سيخلق وجهة نظر لتظهر لك البيانات كما لو كان جدول:

create or replace view t2
as
select 
    account, bookdate, amount, 
    sum(amount) over (partition by account order by bookdate) running_total 
from t
/

إذا كنت حقا بحاجة الجدول، هل يعني أنك في حاجة إليها تحديثها باستمرار؟ أو مجرد مرة واحدة؟ من الواضح ما اذا كان لمرة واحدة يمكنك فقط "إنشاء الجدول كما حدد" باستخدام الاستعلام أعلاه.

واختبار البيانات I المستخدمة هي:

create table t(account number, bookdate date, amount number);

insert into t(account, bookdate, amount) values (1, to_date('20080101', 'yyyymmdd'), 100);

insert into t(account, bookdate, amount) values (1, to_date('20080102', 'yyyymmdd'), 101);

insert into t(account, bookdate, amount) values (1, to_date('20080103', 'yyyymmdd'), -200);

insert into t(account, bookdate, amount) values (2, to_date('20080102', 'yyyymmdd'), 200);

commit;

وتحرير:

ونسيت أن أضيف؛ الذي حددته التي أردت الجدول إلى أن يؤمر - وهذا لا يجعل حقا معنى، ويجعلني أعتقد أن كنت حقا يعني أن أردت الاستعلام / عرض - طلب هو نتيجة الاستعلام تقوم بتنفيذ، لا شيء هذا inherant في الجدول (تجاهل جداول مؤشر المنظمة وما شابه ذلك).

نصائح أخرى

سأبدأ بهذا التحذير المهم جداً:لا تقم بإنشاء جدول للاحتفاظ بهذه البيانات.عندما تفعل ذلك ستجد أنك بحاجة إلى الحفاظ عليه مما سيصبح صداعًا لا ينتهي أبدًا.اكتب طريقة عرض لإرجاع العمود الإضافي إذا كنت تريد القيام بذلك.إذا كنت تعمل مع مستودع بيانات إذن ربما ستفعل شيئًا كهذا، ولكن حتى بعد ذلك تخطئ في جانب العرض إلا إذا لم تتمكن ببساطة من الحصول على الأداء الذي تحتاجه باستخدام الفهارس والأجهزة المناسبة وما إلى ذلك.

إليك استعلام سيعيد الصفوف بالطريقة التي تريدها.

SELECT
    Account,
    Bookdate,
    Amount,
    (
        SELECT SUM(Amount)
        FROM My_Table T2
        WHERE T2.Account = T1.Account
          AND T2.Bookdate <= T1.Bookdate
    ) AS Running_Total
FROM
    My_Table T1

الحل المحتمل الآخر هو:

SELECT
    T1.Account,
    T1.Bookdate,
    T1.Amount,
    SUM(T2.Amount)
FROM
    My_Table T1
LEFT OUTER JOIN My_Table T2 ON
    T2.Account = T1.Account AND
    T2.Bookdate <= T1.Bookdate
GROUP BY
    T1.Account,
    T1.Bookdate,
    T1.Amount

اختبرهما من حيث الأداء واكتشف أيهما أفضل بالنسبة لك.كما أنني لم أختبرها بشكل شامل بما يتجاوز المثال الذي قدمته، لذا تأكد من اختبار بعض الحالات المتطورة.

واستخدام التحليلات، مثلما هو الحال في سؤالك الأخير:

create table accounts
( account number(10)
, bookdate date 
, amount   number(10)
);

delete accounts;

insert into accounts values (1,to_date('20080101','yyyymmdd'),100);
insert into accounts values (1,to_date('20080102','yyyymmdd'),101);
insert into accounts values (2,to_date('20080102','yyyymmdd'),200);
insert into accounts values (1,to_date('20080103','yyyymmdd'),-200);

commit;

select account
,      bookdate 
,      amount
,      sum(amount) over (partition by account order by bookdate asc) running_total
from accounts
order by account,bookdate asc
/

والإخراج:

   ACCOUNT BOOKDATE     AMOUNT RUNNING_TOTAL
---------- -------- ---------- -------------
         1 01-01-08        100           100
         1 02-01-08        101           201
         1 03-01-08       -200             1
         2 02-01-08        200           200
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top