有两张桌子:
CREATE TABLE IF NOT EXISTS `issue_details` (
`id` INT NOT NULL AUTO_INCREMENT ,
amt_offer_dlr INT NOT NULL DEFAULT 9999 COMMENT '564,510,000',
maturity DATE NOT NULL DEFAULT '1111-11-11' COMMENT '06/28/2012' ,
fk_cusip6 VARCHAR(6) NOT NULL DEFAULT '' COMMENT '' ,
PRIMARY KEY (id),
CONSTRAINT con_issue_details__issuers FOREIGN KEY (fk_cusip6) REFERENCES issuers (fk_cusip6) ON DELETE NO ACTION ON UPDATE CASCADE
)
ENGINE = InnoDB;
CREATE TABLE IF NOT EXISTS `identifiers` (
id INT NOT NULL AUTO_INCREMENT ,
fk_cusip6 VARCHAR(6) NOT NULL DEFAULT 'NA' ,
PRIMARY KEY (id) ,
CONSTRAINT con_ident__cusip6 FOREIGN KEY (fk_cusip6) REFERENCES cusip_6 (cusip6) ON DELETE NO ACTION ON UPDATE CASCADE ,
)
COMMENT ''
ENGINE = InnoDB;
issue_details表: 注意:每个id都不同 可以有多个相同的fk_cusip6号码
+-----+--------------+------------+----------------+
| id | maturity | fk_cusip6 | amt_offer_dlr |
+-----+--------------+------------+----------------+
| 1 | 2013-06-28 | 567090 | 1000 |
| 2 | 2014-06-05 | 567090 | 1000 |
| 3 | 2013-06-05 | 567100 | 2500 |
| 3 | 2014-06-05 | 567100 | 2500 |
+-----+--------------+------------+----------------+
标识符表: 注意:每个fk_cusip6号都不同
+--------+-----------+
| id | fk_cusip6 |
+--------+-----------+
| 131472 | 567090 |
| 131473 | 567100 |
+--------+-----------+
我需要生成一个查询,该查询将匹配标识符表中的每个fk_cusip6实例,然后对issue_details表中具有相同fk_cusip6的所有实例求和amt_offer_dlr。最终结果应该是:
+--------------+---------+------------------------+
| ide.id | isd.fk_cusip6 | SUM(isd.Amt_Offer_Dlr |
+--------------+---------+------------------------+
| 131472 | 567090 | 2000 |
| 131473 | 567100 | 5000 |
+--------------+---------+------------------------+
我试过了:
SELECT CURRENT_DATE, FORMAT(SUM(isd.Amt_Offer_Dlr),0) 'Current Out Standing Debt:'
from muni.issue_details isd
INNER JOIN identifiers ide ON ide.fk_cusip6 = isd.fk_cusip6 AND isd.fk_cusip6 = '567541'
where isd.maturity > CURRENT_DATE
;
这是对所有列的总结。
我想我需要一个子查询,但我仍然坚持细节。
由于
答案 0 :(得分:2)
试试这个:
SELECT
i.id,
i.fk_cusip6,
x.amt_offer_dlr_sum
FROM identifiers i
INNER JOIN (
SELECT
id.fk_cusip6,
SUM(id.amt_offer_dlr) AS amt_offer_dlr_sum
FROM issue_details id
GROUP BY id.fk_cusip6
) x
ON x.fk_cusip6 = i.fk_cusip6;
答案 1 :(得分:2)
将SQL中的查询过程视为三阶段活动。这可能无法捕捉真实情况的所有丰富性,但在您的情况下它在逻辑上是准确的。
让我们简化查询以删除日期/成熟度检查并检查单个fk_cusip6值,因此它只是:
SELECT SUM(isd.Amt_Offer_Dlr)
FROM muni.issue_details isd
INNER JOIN identifiers ide ON ide.fk_cusip6 = isd.fk_cusip6
第一阶段是表的连接,以生成要考虑的所有行的列表。因此,在上面的简化示例中,我们正在查看在fk_cusip6上的issue_details和标识符匹配之间的连接。此阶段生成一个包含四行的列表(每个issue_details行一个,并添加相应的标识符行。)
这给你一个像这样的结构:
+-----+--------------+------------+----------------+---------+----------------+
| id | maturity | fk_cusip6 | amt_offer_dlr | ide.id | ide.fk_cusip6 |
+-----+--------------+------------+----------------+---------+----------------+
| 1 | 2013-06-28 | 567090 | 1000 | 131472 | 567090 |
| 2 | 2014-06-05 | 567090 | 1000 | 131472 | 567090 |
| 3 | 2013-06-05 | 567100 | 2500 | 131473 | 567100 |
| 3 | 2014-06-05 | 567100 | 2500 | 131473 | 567100 |
+-----+--------------+------------+----------------+---------+----------------+
现在,这样的非聚合SQL语句:
SELECT *
FROM muni.issue_details isd
INNER JOIN identifiers ide ON ide.fk_cusip6 = isd.fk_cusip6
只会返回该表。但是你有一个与SUM()的聚合,所以我们进入第二阶段。
第二阶段确定应将哪些行拼凑在一起以执行聚合。我说bucketed,但在SQL术语中我们会说哪些行组合在一起,这意味着可能使用GROUP BY子句。但是,在我们的查询中,没有GROUP BY子句,因此查询处理器必须选择将所有行分组到一个存储桶中。这不是您想要的,但如果没有关于如何对行进行分组的任何说明,这就是处理器必须执行的操作。因此,您的聚合将对所有四行执行单个聚合。
第三阶段是实际的聚合本身。这是我们总结所有四行结果的地方。在上面的示例查询中,我们只会看到1000 + 1000 + 2500 + 2500或7000的输出。再次,不是您想要的。
现在考虑这个替代查询:
SELECT ide.id, isd.fk_cusip6, SUM(isd.Amt_Offer_Dlr)
FROM muni.issue_details isd
INNER JOIN identifiers ide ON ide.fk_cusip6 = isd.fk_cusip6
GROUP BY ide.id, isd.fk_cusip6
此查询的第一阶段与之前相同;由于内部联接,会生成四行。
在第二阶段,现在我们有一个GROUP BY,因此查询处理器会将第一阶段的行分配到每个identifier.id值的独立存储桶中。所以我们得到这样的东西:
+ ------- + ----- + + -------------- ------------ + ---- ------------ + --------- + ----------------- + |斗| id |成熟度| fk_cusip6 | amt_offer_dlr | ide.id | iden.fk_cusip6 | | ------- + ----- + -------------- + ------------ + ------- --------- --------- + + + ----------------- | A | 1 | 2013-06-28 | 567090 | 1000 | 131472 | 567090 | | A | 2 | 2014-06-05 | 567090 | 1000 | 131472 | 567090 | | ------- + ----- + -------------- + ------------ + ------- --------- --------- + + + ----------------- | B | 3 | 2013-06-05 | 567100 | 2500 | 131473 | 567100 | | B | 3 | 2014-06-05 | 567100 | 2500 | 131473 | 567100 | + ------- + ----- + -------------- + ------------ + ------- --------- + --------- + ------------------- +
(抱歉,我无法弄清楚如何格式化这个表格)
Bucket A是所有行,其标识符为.id = 131472,而存储桶B的标识符为.id = 131473。
第三阶段为每个桶执行聚合,为您提供所需的结果:
+--------------+---------+------------------------+
| ide.id | isd.fk_cusip6 | SUM(isd.Amt_Offer_Dlr |
+--------------+---------+------------------------+
| 131472 | 567090 | 2000 |
| 131473 | 567100 | 5000 |
+--------------+---------+------------------------+
只要您想要应用的其他搜索条件很简单,我认为您不需要子查询。但即便如此,如果标准变得更复杂,您必须弄清楚它们是进入子查询,连接子句还是整个WHERE子句本身,这可能会导致混淆。我尽量保持选择尽可能简单。