如何从连接三个表的 Derby 数据库中获取聚合和列数据
How to get aggregate and column data from Derby database joining three tables
我需要在 JTable 中显示来自 Derby 数据库的数据,但其中两列是来自两个一对多相关 table 的聚合总和。以下是示例架构:
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 语句中将聚合表达式与 "non-aggregate expressions" 结合起来:
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 子句可以解决这些情况,但我想从第三个 table 添加到第二个聚合会让我失望。我试过 GROUP BY S.NET_SALES, S.SALES_TAX, 并在 WHERE 子句中添加 AND S.ID = 278 得到一个已知的结果,TOTAL_PAIDOUTS 是正确的(有 3 个相关OTHERPAIDOUTS 中的记录),但返回的 TOTAL_DISCOUNTS 是应有的 3 倍。
不用说,我不是SQL程序员!希望你明白我所追求的要点。我试过嵌套的 SELECT 语句,但把它弄得一团糟。这个应用程序仍在开发中,包括数据库结构,所以如果不同的数据库结构可以简化事情,那可能是一个选择。或者,如果有另一种方法可以以编程方式构建 table 模型,我也愿意接受。提前致谢!!
========编辑=============
为了检查已知记录的值,我正在查询特定的 SHIFTDATA.ID。以下是示例 table 记录:
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
试试 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
这是具有所需结果的 SQL 查询。
这里是 table 定义、数据、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 |
+------+----------+----------+----------------+----------------+
我需要在 JTable 中显示来自 Derby 数据库的数据,但其中两列是来自两个一对多相关 table 的聚合总和。以下是示例架构:
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 语句中将聚合表达式与 "non-aggregate expressions" 结合起来:
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 子句可以解决这些情况,但我想从第三个 table 添加到第二个聚合会让我失望。我试过 GROUP BY S.NET_SALES, S.SALES_TAX, 并在 WHERE 子句中添加 AND S.ID = 278 得到一个已知的结果,TOTAL_PAIDOUTS 是正确的(有 3 个相关OTHERPAIDOUTS 中的记录),但返回的 TOTAL_DISCOUNTS 是应有的 3 倍。
不用说,我不是SQL程序员!希望你明白我所追求的要点。我试过嵌套的 SELECT 语句,但把它弄得一团糟。这个应用程序仍在开发中,包括数据库结构,所以如果不同的数据库结构可以简化事情,那可能是一个选择。或者,如果有另一种方法可以以编程方式构建 table 模型,我也愿意接受。提前致谢!!
========编辑=============
为了检查已知记录的值,我正在查询特定的 SHIFTDATA.ID。以下是示例 table 记录:
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
试试 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
这是具有所需结果的 SQL 查询。
这里是 table 定义、数据、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 |
+------+----------+----------+----------------+----------------+