简体   繁体   English

如何引用相关表的多个和作为子查询

[英]How to reference multiple sums of a related table as a subquery

I have a table of data I need to pull out each row. 我有一个数据表,我需要提取每一行。 This table ( A ) has a many-to-one relationship to another table B (many instances of A referenced in B . 该表( A )与另一个表B具有多对一关系( B引用了A许多实例)。

I want to output each row of A with numerous SUM's of values of B ; 我想输出A每一行以及B的值的许多SUM; I can think of doing this with Sub-Select's but they feel inefficient and a bit repetative. 我可以考虑使用Sub-Select来做到这一点,但是他们觉得效率低下,而且有点重复。

There are 3 columns in B that need to be summed. B中需要累加3列。 I (feel I) can not JOIN these tables because sometimes A will not appear in B at all, and often A will appear multiple times. 我(觉得我)无法JOIN这些表,因为有时A根本不会出现在B中,并且经常A会出现多次。

What I've read: 我读过的东西:

Amongst other things; 除其他事项外;

I don't feel these have helped me due to various reasons; 由于种种原因,我觉得这些都没有帮助我。 people suggest JOIN's but I don't think I can use JOINs due to having 0+ number of related rows. 人们建议使用JOIN,但由于相关行数为0+,因此我不认为可以使用JOIN。 Also some answers are too specific to the questions so don't seem to help in my situation. 另外,某些问题的答案过于具体,因此对我的情况似乎没有帮助。

What I've Got: 我得到了什么:

Example Data, table creation: 示例数据,表创建:

    CREATE TABLE Countries (
    Id INT NOT NULL AUTO_INCREMENT,
    ISO VARCHAR(2) NOT NULL,
    ISO3 VARCHAR(3) NOT NULL,
    ISONumeric INT NOT NULL,
    CountryName VARCHAR(64) NOT NULL,
    Capital VARCHAR(64) NOT NULL,
    CurrencyCode VARCHAR(3) NOT NULL,
    PRIMARY KEY(Id)
);

CREATE TABLE Cities (
    cId INT NULL AUTO_INCREMENT,
    CityName VARCHAR(64) NOT NULL,
    Population INT(7) NOT NULL, 
    Natives INT(7) NOT NULL,
    Country TINYINT(3) NOT NULL,
    PRIMARY KEY(cId)
);

INSERT INTO Countries
    (ISO, ISO3, ISONumeric, CountryName, Capital, CurrencyCode)
VALUES
    ('AU', 'AUS', 36, 'Australia', 'Canberra',  'AUD'),
    ('DE', 'DEU', 276, 'Germany', 'Berlin',  'EUR'),
    ('GB', 'UKG', 1, 'Britain', 'London',  'GBP'),
    ('IN', 'IND', 356, 'India', 'New Delhi',  'INR'),
    ('LA', 'LAO', 418, 'Laos', 'Vientiane',  'LAK'),
    ('US', 'USA', 840, 'United States', 'Washington',  'USD'),
    ('ZW', 'ZWE', 716, 'Zimbabwe', 'Harare', 'ZWL')
;

INSERT INTO Cities
    (CityName, Population, Natives, Country)
VALUES
    ('London', 6431000, 1362434, 3),
    ('Sheffield', 136000, 1434, 3),
    ('Luton', 61000, 134, 3),
    ('Munich', 231000, 134214, 2),
    ('New York', 12131000, 16, 6),
    ('Washington', 210700, 343, 6)
;

Example Query generation: 查询生成示例:

SELECT Countries.*, 
(SELECT SUM(`Population`) FROM Cities WHERE `Country` = `Countries`.`Id` ) as pop,
(SELECT SUM(`Natives`) FROM Cities WHERE `Country` = `Countries`.`Id` ) as native
FROM Countries

This query works, but I have a perception it can easily become extremely cumbersome. 该查询有效,但是我认为它很容易变得非常麻烦。 It appears to be multipe SELECTs on the same table ( Cities ) (My examples shows two SUM selects but I will eventually have many more). 它似乎是在同一张表( Cities )上的MULTI SELECT(我的示例显示了两个SUM选择,但最终我会有更多选择)。

SQL Fiddle: SQL提琴:

http://www.sqlfiddle.com/#!9/9d5d47/4 http://www.sqlfiddle.com/#!9/9d5d47/4

What's My Issue? 我的问题是什么?

I want to easily be able to SUM(...) various columns of B relating to A to add as an output when dumping the contents of A . 我希望能够轻松地SUM(...)的各列BA倾倒的内容时,添加为一个输出A There may be zero or more occurances of A referenced in B . B引用的A可能出现零次或多次。

How should I do this with more efficiency and less repetition than numerous Subqueries? 与众多子查询相比,我应该如何以更高的效率和更少的重复进行此操作?

For example is it possible to combine all the SUM's into a single subquery? 例如,是否可以将所有SUM合并为一个子查询?

If I guess correct, your query should be as below- 如果我认为正确,则您的查询应如下所示-

DEMO HERE 此处演示

SELECT 
A.column_1,A.column_2,A.column_3,  -- LIST your required columns from table  Countries
SUM(B.Population) as pop,
SUM(B.Natives) as native
FROM Countries A
LEFT JOIN Cities B ON B.Country = A.Id 
GROUP BY A.column_1,A.column_2,A.column_3 -- GROUP BY with same columns in select list

You might find this easier by aggregating before joining: 通过加入之前进行汇总您可能会发现这更容易:

SELECT co.*, ci.pop, ci.natives
FROM Countries co LEFT JOIN
     (SELECT ci.Country,
             SUM(ci.Population) as pop,
             SUM(ci.Natives) as native
      FROM Cities ci 
      GROUP BY ci.Country
     ) ci
     ON ci.Country = co.Id ;

This eliminates the need to repeat all the columns in the country table. 这消除了重复country表中所有列的需要。 If the JOIN keys are the same, you can simplify this to: 如果JOIN键相同,则可以简化为:

SELECT *
FROM Countries co LEFT JOIN
     (SELECT ci.Country as id,
             SUM(ci.Population) as pop,
             SUM(ci.Natives) as native
      FROM Cities ci 
      GROUP BY ci.Country
     ) ci
     USING (id);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM