如何从联接三个表的Derby数据库中获取聚合和列数据

时间:2018-12-04 10:04:04

标签: java swing derby

我需要在JTable中显示来自Derby数据库的数据,但是其中两列是来自两个一对多相关表的汇总和。这是示例架构:

SHIFTDATA:
    ID
    DATE
    SHIFT
    FOOD_COST
    OFFICE_SUPPLIES
    REP_MAINT
    NET_SALES
    SALES_TAX

OTHERPAIDOUTS:
    ID
    SHIFTDATA_ID
    LABEL
    AMOUNT

DISCOUNTS
    ID
    SHIFTDATA_ID
    DISCOUNT_NAME
    AMOUNT

给定的SHIFTDATA有0个或更多OTHERPAIDOUTS

给定的SHIFTDATA有0个或多个折扣

尽管我知道我无法在SELECT语句中将聚合表达式与“非聚合表达式”组合在一起,但我需要使用此语句的等效项:

SELECT (S.FOOD_COST + S.OFFICE_SUPPLIES + S.REP_MAINT + SUM(O.AMOUNT)) AS TOTAL_PAIDOUTS, 
SUM(D.AMOUNT) AS TOTAL_DISCOUNT, 
S.NET_SALES,
S.SALES_TAX
FROM SHIFTDATA S, OTHERPAIDOUTS O, DISCOUNTS D WHERE O.SHIFTDATA_ID=S.ID AND D.SHIFTDATA_ID=S.ID

我在其他线程中看到添加GROUP BY子句可以解决这些情况,但是我猜想从第三张表中添加第二个聚合将使我失望。我尝试了GROUP BY S.NET_SALES,S.SALES_TAX,并将AND S.ID = 278添加到WHERE子句中以获得已知结果,并且TOTAL_PAIDOUTS是正确的(OTHERPAIDOUTS中有3个相关记录),但是返回的TOTAL_DISCOUNTS是应该是它的3倍。

不用说,我不是SQL程序员!希望你能明白我的追求。我尝试了嵌套的SELECT语句,但只是弄乱了。该应用程序仍在开发中,包括数据库结构,因此,如果使用其他数据库结构可以简化操作,则可以选择。或者,如果还有另一种以编程方式构建表模型的方法,我也乐于接受。在此先感谢!

=========编辑============

为了检查已知记录中的值,我在查询特定的SHIFTDATA.ID。以下是样本表记录:

SHIFTDATA:
ID  |FOOD_COST |OFFICE_SU&|REP_MAINT |NET_SALES |SALES_TAX
------------------------------------------------------
278 |0.00      |5.00      |10.00     |3898.78   |319.79

OTHERPAIDOUTS:
ID         |SHIFTDATA_&|LABEL                                   |AMOUNT
---------------------------------------------------------------------------
37         |278        |FOOD COST FUEL                          |52.00
38         |278        |MAINT FUEL                              |5.00
39         |278        |EMPLOYEE SHOES                          |21.48

DISCOUNTS:
ID         |ITEM_NAME                               |SHIFTDATA_&|AMOUNT
---------------------------------------------------------------------------
219        |Misc Discounts                          |278        |15.91

我希望在JTable中的此SHIFTDATA行看到什么:

TOTAL_PAIDOUTS | TOTAL_DISCOUNT |NET_SALES |SALES_TAX
------------------------------------------------------
93.48          |15.91           |3898.78   |319.79

我能得到的最好的结果是添加GROUP BY子句,但是按SHIFTDATA的字段分组,我得到了:

TOTAL_PAIDOUTS | TOTAL_DISCOUNT |NET_SALES |SALES_TAX
------------------------------------------------------
93.48          |47.73           |3898.78   |319.79

2 个答案:

答案 0 :(得分:1)

尝试LEFT OUTER JOIN,如下所示:

SELECT S.FOOD_COST + S.OFFICE_SUPPLIES + S.REP_MAINT + SUM(O.AMOUNT) AS TOTAL_PAIDOUTS, 
       SUM(D.AMOUNT) AS TOTAL_DISCOUNT, 
       S.NET_SALES,
       S.SALES_TAX
FROM SHIFTDATA S
LEFT JOIN OTHERPAIDOUTS AS O ON O.SHIFTDATA_ID = S.ID
LEFT JOIN DISCOUNTS AS D     ON D.SHIFTDATA_ID = S.ID

编辑

SELECT S.FOOD_COST + S.OFFICE_SUPPLIES + S.REP_MAINT +
       ( SELECT COALESCE(SUM(AMOUNT), 0) FROM OTHERPAIDOUTS WHERE SHIFTDATA_ID = S.ID ) AS TOTAL_PAIDOUTS,
       ( SELECT COALESCE(SUM(AMOUNT), 0) FROM DISCOUNTS     WHERE SHIFTDATA_ID = S.ID ) AS TOTAL_DISCOUNT,
       S.NET_SALES,
       S.SALES_TAX
FROM SHIFTDATA S

答案 1 :(得分:1)

这是具有所需结果的SQL查询。

以下是表定义,数据,sql和结果:

CREATE TABLE shiftdata (
    id int,
    foodcost int,
    officesuppl int,
    repmaint int,
    netsales int,
    salestax int);

CREATE TABLE otherpaidouts (
    id int,
    shiftid int,
    label varchar(20),
    amount int);

CREATE TABLE discounts (
    id int,
    shiftid int,
    itemname varchar(20),
    amount int);

创建两个班次的数据:278和333。两个班次都有discounts,但是只有278个班次都有otherpaidouts

insert into shiftdata values (278, 0, 5, 10, 3898, 319);
insert into shiftdata values (333, 22, 15, 100, 2111, 88);
insert into otherpaidouts values (37, 278, 'Food Cost FUEL', 52);
insert into otherpaidouts values (38, 278, 'Maint FUEL', 5);
insert into otherpaidouts values (39, 278, 'Empl SHOES', 21);
insert into discounts values (219, 278, 'Misc DISCOUNTS', 15);
insert into discounts values (312, 333, 'Misc DISCOUNTS', 25);


查询:

SELECT sd.id, sd.netsales, sd.salestax,
  IFNULL(
    (SELECT SUM(d.amount) FROM discounts d WHERE d.shiftid=sd.id), 0) AS total_discount,
  (SELECT sd.foodcost + sd.officesuppl + sd.repmaint + IFNULL(SUM(op.amount), 0) FROM otherpaidouts op WHERE op.shiftid=sd.id) AS total_paidouts
FROM shiftdata sd;


结果:

+------+----------+----------+----------------+----------------+
| id   | netsales | salestax | total_discount | total_paidouts |
+------+----------+----------+----------------+----------------+
|  278 |     3898 |      319 |             15 |             93 |
|  333 |     2111 |       88 |             25 |            137 |
+------+----------+----------+----------------+----------------+