2012-07-07 48 views
5

Bàn sử dụng:truy vấn SQL để chọn một cột với biểu hiện của giá trị không tổng hợp và chức năng tổng hợp

1) v (ngày d, tên c (25), desc c (50), n ghi nợ (7), tín dụng n (7))

tên trong 'v' là tên trong bảng vn

2) vn (ngày d, tên c (25), loại c (25), obal n (7))

tên trong 'vn' là khóa chính và các tên khác nhau được nhóm theo loại

ví dụ: tên abc, def, writing thuộc về gõ 'ngân hàng', tên xyz, pqr thuộc về gõ 'sổ', ...

Tôi đã một truy vấn như thế này:

Nó hoạt động tốt nhưng vấn đề duy nhất là, obal là một giá trị được nhập chỉ một lần cho mỗi tên trong bảng 'vn' nhưng với truy vấn này cho mỗi phép tính ghi nợ tín dụng trong bảng 'v', obal được thêm nhiều lần và hiển thị dưới dạng OpBal. Khi truy vấn được sửa đổi như dưới đây:

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 

nó hiển thị thông báo lỗi như 'Nhóm theo mệnh đề bị thiếu hoặc không hợp lệ'!

RDBMS sử dụng MS Visual Foxpro 9. sd và ed là các biến kiểu ngày được sử dụng cho mục đích truy vấn nơi sd < ed.

Hãy giúp tôi nhận kết quả mong đợi. Cảm ơn rất nhiều.

+0

Bạn cần nhóm theo bảng 'vn' và sau đó kết hợp kết quả đó với truy vấn bạn có. –

+0

@Dem: Tôi đã nghĩ điều cần thiết cho truy vấn 'GROUP BY vn.type'. Với một loại 'GROUP BY, obal', tôi nghĩ câu trả lời của bạn là tốt. (Nhân tiện, cái này là 'HAVING' sau cú pháp hợp lệ 'ORDER BY' trong Foxpro? Nó làm tôi băn khoăn) –

+0

Và tôi giả định rằng Khóa chính của' vn' là 'name', theo mô tả. –

Trả lời

0

tôi thấy Cú pháp SQL cho SQL với VFP cho lần đầu tiên một vài phút trước, vì vậy đây cũng có thể là đầy đủ các lỗi, nhưng như là một 'linh cảm guessful':

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 

Về cơ bản, tôi ve chỉ cần lựa chọn từ v vào subselects để tránh vn.obal được lặp đi lặp lại. Nó không nên quan trọng với v rằng nó đầu tiên nhận được số tiền cho người cá nhân trước khi tổng hợp tất cả chúng lại với nhau.

+0

Đặt, xin lỗi! Nó tạo ra một thông báo lỗi: 'Tên chức năng bị thiếu).' – Ganapathy

0

chỉ là một vài điều. VFP 9 có một thiết lập để không yêu cầu nhóm cho tất cả không tổng hợp cho tương thích ngược và kết quả tương tự như MySQL, nơi không phải tất cả các cột phải được tổng hợp. Chẳng hạn như truy vấn thêm cột từ bản ghi của khách hàng không bao giờ thay đổi bất kể bạn có bao nhiêu hồ sơ tham gia vào cột PK của nó (tên, địa chỉ, điện thoại, bất kỳ thứ gì).

SET ENGINEBEHAVIOR 80 

mặc định cho VFP 9

SET ENGINEBEHAVIOR 90 

yêu cầu tất cả không nhóm theo cột được uẩn để tuân thủ.

Tiếp theo ... có vẻ như bạn có các cột rất xấu trong bảng bạn đang xử lý ... 3 từ dành riêng trong VFP ... "ngày", "Tên" và "loại", tuy nhiên bạn vẫn ổn bằng cách đủ điều kiện trong truy vấn với tham chiếu alias.column.

Mã mẫu sau sẽ tạo bảng tạm thời (con trỏ) của cấu trúc bạn đã mô tả trong câu hỏi của bạn.Tôi cũng đã chèn một số dữ liệu mẫu và mô phỏng của bạn "sd" (ngày bắt đầu) và "ed" (ngày kết thúc) biến

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... 

Bây giờ, truy vấn ... Bạn đang cố gắng để có được nhóm theo loại nhưng mỗi người (tên) cần phải được tổng hợp trước trên cơ sở mỗi người FIRST. Bây giờ, có vẻ như bạn đang cố gắng có được tổng số dư giao dịch mở trước ngày bắt đầu (sd) làm cơ sở tại một thời điểm cụ thể, sau đó xem hoạt động WITHIN ngày bắt đầu/kết thúc được đề cập. Thực hiện điều này trước, nhưng không giải quyết việc thêm vào cột "obal" từ bảng "vn". Vì nó cần tổng hợp các nhóm không theo cột, tôi sẽ chỉ sử dụng "MAX()" của cột. Vì nó là bởi một PK (tên) cơ sở, bạn sẽ kết thúc với bất cứ điều gì nó được, nhưng với tổng số cuộn lên của các giao dịch, nhưng có tất cả dữ liệu của bạn trước khi tóm tắt thành một hàng duy nhất thông qua ...

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 

với kết quả này (từ dữ liệu mẫu của tôi) sẽ như thế nào ...

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

tổng hợp cuối cùng của bạn để có được theo loại, bạn chỉ có thể truy vấn kết quả trên "con trỏ" (C_JustByName) và sử dụng CNTT để nhóm theo loại, có, v.v ... giống như

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 

Bây giờ, tôi chỉ đơn giản hóa ở trên bởi vì tôi không biết những gì bạn đang thực sự tìm kiếm như ngày trong "VN" của bạn (xuất hiện giống như một bảng khách hàng) với một ngày không rõ mục đích của nó và Cột oBal đối với bảng giao dịch.

Điều thú vị về VFP là bạn có thể truy vấn vào con trỏ tạm thời mà không cần tạo bảng vĩnh viễn và sử dụng CNTT làm cơ sở cho bất kỳ truy vấn nào sau đó ... Nó giúp không đọc được truy vấn bên trong truy vấn bên trong truy vấn. Nó cũng cho phép bạn xem kết quả của từng lớp và biết rằng bạn đang nhận được câu trả lời bạn đang EXPECTING trước khi tiếp tục đến giai đoạn truy vấn tiếp theo ...

Hy vọng điều này sẽ giúp bạn theo hướng bạn đang cố gắng giải quyết .

Các vấn đề liên quan