0

我正在尝试创建一个程序,在该程序中,给定一个战斗名称,生成在那场战斗中的两个国家。(如果不完全是两个国家,则为两个国家生成 NULL)

该程序的第一部分对我来说并不重要(我认为)

SELECT ship FROM outcomes WHERE battle = inBattle AS t1;
SELECT DISTINCT class FROM ships WHERE name IN t1 AS t2;
SELECT DISTINCT country FROM classes WHERE class IN t2;

我认为这会给我一个表格,其中列出了特定战斗中的不同国家。当我尝试做第二部分时,我的问题就出现了,如果不是完全找到两个国家,那么这两个国家都会产生 NULL。

CREATE PROCEDURE findCountriesInBattle( in inBattle VARCHAR(50) )
BEGIN
    SELECT ship FROM outcomes WHERE battle = inBattle AS t1;
    SELECT DISTINCT class FROM ships WHERE name IN t1 AS t2;
    SELECT DISTINCT country FROM classes WHERE class IN t2 AS t3;
IF(SELECT COUNT(*) FROM t3 < 2 OR SELECT COUNT(*) FROM t3 > 2)
    [show NULL, NULL]; << Line 1
ELSE
    SELECT * FROM t3; << Line 2
END IF;
END;
// 

我如何正确编写第 1 行和第 2 行?其他线路对吗?

关系:

classes(class, type, country, numGuns, bore, displacement)
ships( name, class, launched)
battles(name, date)
outcomes(ship, battle, result)
4

1 回答 1

0

您应该使用表连接来简化基本查询。您可以通过一个 SELECT 查询将 3 个表连接在一起,获得给定战斗的不同国家/地区列表。

由于您正在编写存储过程,因此一种直接的方法是首先将计数选择到局部变量中,然后使用条件来显示国家名称或适当的空值。

这是基于您的源代码的示例:

CREATE PROCEDURE findCountriesInBattle( in inBattle VARCHAR(50) )
BEGIN
   DECLARE v_country_count INT;

  -- count the countries involved in the battle
  SELECT COUNT(DISTINCT classes.country)
  INTO V_COUNTRY_COUNT
  FROM outcomes
  INNER JOIN ships ON ships.name = outcomes.ship
  INNER JOIN classes ON classes.class = ships.class
  WHERE outcomes.battle = inBattle;

  IF (v_country_count = 2)
  THEN
    -- if it was exactly 2, output the names
    SELECT DISTINCT classes.country
    FROM outcomes
    INNER JOIN ships ON ships.name = outcomes.ship
    INNER JOIN classes ON classes.class = ships.class
    WHERE outcomes.battle = inBattle; 
  ELSE
    -- otherwise, output NULL,NULL
    SELECT null
    UNION ALL
    SELECT null;  
  END IF;
END;
// 
于 2012-04-23T19:40:07.937 回答