Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/78.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 关于计数的复杂SQL查询_Mysql_Sql - Fatal编程技术网

Mysql 关于计数的复杂SQL查询

Mysql 关于计数的复杂SQL查询,mysql,sql,Mysql,Sql,以下是两个带有模式的表: 船舶(名称、下水年份、国家、数量、口径、排水量) 战斗(船、战斗名、结果) 典型的Ships元组是: (《新泽西州》,1943年,《美国》,9、16、46000年) 也就是说新泽西号战舰是在1943年发射的;它属于美国,携带9门16英寸口径(口径或枪管内径)的大炮,重量(以航海术语计算)为46000吨 战斗的典型元组是: (‘胡德’、‘北大西洋’、‘沉没’) 也就是说,H.M.S.胡德号是在北大西洋战役中被击沉的。其他可能的结果是“正常”和“损坏” 下面是一个棘手的问题

以下是两个带有模式的表:

船舶(名称、下水年份、国家、数量、口径、排水量)
战斗(船、战斗名、结果)

典型的Ships元组是:

(《新泽西州》,1943年,《美国》,9、16、46000年)

也就是说新泽西号战舰是在1943年发射的;它属于美国,携带9门16英寸口径(口径或枪管内径)的大炮,重量(以航海术语计算)为46000吨

战斗的典型元组是:

(‘胡德’、‘北大西洋’、‘沉没’)

也就是说,H.M.S.胡德号是在北大西洋战役中被击沉的。其他可能的结果是“正常”和“损坏”

下面是一个棘手的问题: 对于苏里高海峡战役,对于参与该战役的每个国家(有一艘或多艘战舰参与),请给出其战舰沉没的数量。注意:这个问题很棘手。特别是,您需要处理一个国家参与战斗但没有任何船只沉没的(历史)案例。

到目前为止我都试过了

SELECT country,COUNT(name) 
FROM ships RIGHT JOIN battles 
      ON ships.name=battles.ship 
WHERE battleName='Battle1' AND result='sunk' 
GROUP BY country

您需要加入这些表,我猜与其他表的关系是通过
船名来实现的。试试这个

SELECT  a.country, 
        SUM(CASE WHEN b.result = 'SUNK' THEN 1 ELSE 0 END) totalSunkShips,
        SUM(CASE WHEN b.result = 'OK' THEN 1 ELSE 0 END) totalUNSunkShips
FROM    battles a
        INNER JOIN ships b
            ON a.ship = b.name
WHERE   b.battleName = 'Surigao Strait'
GROUP BY a.country
参加那场战斗的国家(有一艘或多艘战舰) (参与)

这意味着在战斗名称为“苏里高海峡”的战斗中至少有一次记录。它表示
内部联接

给出被击沉的战舰数量

这是一个条件计数,下面是“技巧”。你可以使用一个有条件结束的总数,然后你可以计算沉船的数量

SELECT country,SUM(CASE WHEN result = 'sunk' THEN 1 ELSE 0 END) AS TotalShipSunk 
FROM ships 
INNER JOIN battles 
      ON ships.name=battles.ship 
WHERE battleName='Surigao Strait'
GROUP BY country

样本船记录

name                      yearLaunched  country numGuns gunSize displacement
New Jersey                      1943    USA      9       16      46000
Surigao Strait Battle ship USA  1800    USA      9       16      5000
Surigao Strait Battle ship USA  1800    USA      9       16      5000
Surigao Strait Battle ship UK   1800    UK       7       16      27000
Surigao Strait Battle ship France 1800  France   9       16      5000
Surigao Strait Battle ship Urugaya  1800 Urugaya 7       16      27000
New Jersey                       1943    UK      9       16      46000
ship    battleName                                   result
Hood    North Atlantic                                sunk
Surigao Strait Battle ship USA  Surigao Strait        sunk
Surigao Strait Battle ship UK   Surigao Strait        damaged
Surigao Strait Battle ship France   Surigao Strait    ok
Surigao Strait Battle ship Urugaya  Surigao Strait    sunk
战斗记录样本

name                      yearLaunched  country numGuns gunSize displacement
New Jersey                      1943    USA      9       16      46000
Surigao Strait Battle ship USA  1800    USA      9       16      5000
Surigao Strait Battle ship USA  1800    USA      9       16      5000
Surigao Strait Battle ship UK   1800    UK       7       16      27000
Surigao Strait Battle ship France 1800  France   9       16      5000
Surigao Strait Battle ship Urugaya  1800 Urugaya 7       16      27000
New Jersey                       1943    UK      9       16      46000
ship    battleName                                   result
Hood    North Atlantic                                sunk
Surigao Strait Battle ship USA  Surigao Strait        sunk
Surigao Strait Battle ship UK   Surigao Strait        damaged
Surigao Strait Battle ship France   Surigao Strait    ok
Surigao Strait Battle ship Urugaya  Surigao Strait    sunk
这就是你要找的吗

SELECT s.country,Count(s.name) AS Cnt
FROM ships s
JOIN (SELECT * 
        FROM Battles
        WHERE battleName='Surigao Strait' AND result='sunk' )b
ON s.name=b.ship 
GROUP BY s.country
结果

Urugaya 1
USA 2
国家/地区Cnt

Urugaya 1
USA 2

我知道我可以使用所有船只的数量减去未沉没船只的数量,但我不想加入四个表…好问题,你忘了添加你的查询?因为这是作业,请展示你已经尝试过的,我们可以引导你找到解决方案。我们不会为你这样做(嗯,我想吴宇森会的,但他的答案是错误的)。当然,我试过这个:
选择国家,从船上数数(名字),然后在船上加入战斗。name=battles.ship其中battleName='Battle1'和result='sink'按国家分组
,但这一点都不难。我可以同时加入两艘战舰和两场战斗,但我认为这代价太高了。忘了试着一分钟数一次吧。只需写一个查询,给出所有在战斗中沉没的船只以及它们属于哪个国家。那很容易。之后,您可以修改查询,以考虑参与的国家,但没有船只沉没。在那之后,你可以担心聚合。这是我之前的答案,有人投了反对票,我对这句话感到困惑
你需要处理一个(历史)案例,即一个国家参与了战斗,但没有任何船只沉没
我想这意味着在这种情况下我们应该显示'countryName:0',这个查询很有效@Barmar你能解释一下为什么这是错误的吗?我以前没有看到这个答案,但我认为这是正确的。@AndrásOttó因为我删除了它(一个小时前)并再次取消删除。这仍然缺少一点,也许OP只是要求计算那些参加过战斗但还没有沉船的国家(在所有战斗中),我无法创建它,因为OP还没有回答我的问题。@POPOL你试过运行这个查询吗?@JohnWoo还没有,但你的和Andras的一样,所以我认为它会很好地工作。我只是想知道为什么巴尔马认为这是错误的。@POPOL实际上我的第一个答案是错误的,我没有加上没有沉没的船的数量。