0

私は、戦闘名を付けて、その戦闘に参加した2つの国を作成する手順を作成しようとしています。(正確に2つの国がない場合は、両方の国で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;

これにより、特定の戦闘における個別の国のリストが記載された表が得られると思います。2番目の部分を実行しようとすると、問題が発生します。正確に2つの国が見つからない場合、両方の国で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

テーブル結合を使用して、基本的なクエリを簡素化する必要があります。3 つのテーブルを結合する 1 つの SELECT クエリを使用して、特定の戦闘の個別の国のリストを取得できます。

ストアド プロシージャを作成しているため、最初にカウントをローカル変数に選択してから、条件を使用して国名または null を適切に表示するという簡単な方法があります。

ソースコードに基づく例を次に示します。

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 に答える