2012-07-07 79 views
5

表中:SQL查询来选择与非集合值表达和聚集函数列

1)V(日期d,名称C(25),递减C(50),借记N( 7),信用N(7))

名称在 'v' 在VN表是指名称

2)VN(日期d,名称C(25),C型(25),10:28 N(7 ))

'vn'中的名称是主键,不同的名称按类型分组

例如:姓名ABC,DEF,GHI属于输入 '银行',名字XYZ,PQR属于输入 '台账',...

我有这样的查询:

它工作正常,但唯一的问题是,obal是一个值,它只在表'vn'中为每个名称输入一次,但对于表'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 

它显示错误消息,如“组by子句丢失或无效”!

使用RDBMS MS Visual Foxpro 9 sd和ed是用于查询的日期类型变量,其中sd < ed。

请帮我拿出预期的结果。非常感谢。

+0

您需要在'vn'表中进行分组,然后将该结果加入到您的查询中。 – 2012-07-07 08:01:27

+0

@Dems:我在想'GROUP BY vn.type'查询需要什么。用'GROUP BY类型,obal',我认为你的答案没问题。 (顺便说一下,在Foxpro中的'ORDER BY'有效的语法后面是'HAVING'吗?它让我想知道) – 2012-07-07 08:07:07

+0

而且我认为'vn'的主键是'name',通过描述。 – 2012-07-07 08:10:13

回答

0

我看到SQL语法SQL与VFP首次在几分钟前,所以这很可能是完全错误的,但作为一个“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变成子选择,以避免vn.obal重复。对于v而言,在将它们总结在一起之前,它首先得到个人的总和并不重要。

+0

设置,对不起!它产生一个错误信息:'功能名称丢失'。'' – Ganapathy 2012-07-07 15:02:00

0

只是几件事。 VFP 9有一个设置,不需要为所有非聚合进行分组以获得向后兼容性以及类似的结果,如MySQL,其中并非所有列都必须聚合。例如,查询客户记录中的额外列,无论您在PK列(名称,地址,电话,无论)上加入多少条记录都不会改变。

SET ENGINEBEHAVIOR 80 

默认为VFP 9

SET ENGINEBEHAVIOR 90 

要求所有非组按列以聚集体遵守。

接下来......看起来你在处理的表格中有很差的列...... 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... 

现在,查询......你试图通过类型获得团体,但每个人(姓名)需要按照每人的基础进行预先汇总。现在,您似乎试图在开始日期(sd)之前将交易的总期初余额作为给定时间点的基础,然后查看相关开始/结束日期内的活动。首先执行此操作,但不涉及从“vn”表添加“obal”列。由于它需要非列组的聚合,所以我只需使用该列的“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),并用它得到你的分组类型,有,等等...像

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 

现在,我只是简化了上述内容,因为我不知道您真正在寻找什么作为您的“VN”(看起来像客户表)中的日期,并且日期不清楚它的目的和它的目的关于交易表的oBal列。

关于VFP的好处是,你可以查询到一个临时游标,而无需创建一个永久表,并使用IT作为任何查询之后的基础......它有助于不必嵌套查询内部查询内部查询。它还可以让你看到每一层的结果,并知道你正在得到你正在回答的答案,然后继续下一个查询阶段...

希望这会帮助你在你想要解决的方向。