Как использовать коррелированный подзапрос для нового столбца в моем представлении? - PullRequest
0 голосов
/ 05 августа 2010

Я пытаюсь написать представление, которое имеет 3 столбца: Планета, Луна и Самый большой.

Представление предназначено для отображения планет, их лун и столбца Да или Нет, указывающего, действительно ли этоявляется самой большой луной для планеты.

Используется только одна базовая таблица, и столбцы, на которые я ссылаюсь, - это moonPlanetOrbit (только не ноль, если bodyType = = 'Moon'), bodyName (имя луны),и самый большой («да» или «нет»).

Вот моя попытка:

CREATE VIEW Moons (Planet, Moon, Largest)
select moonPlanetOrbited, bodyName, ('Yes' if bodyName = (SELECT top 1 moonMeanRadius from Body where moonPlanetOrbited = bodyName order by moonMeanRadius) as Largest)

Я могу предоставить любую дополнительную информацию, если это необходимо.

СпасибоКоди

Ответы [ 3 ]

1 голос
/ 06 августа 2010

SQL лучше всего работает с наборами данных. Мой совет - получить набор самых больших лун с помощью оператора SELECT и функции MAX (), а затем объединить набор результатов со всей таблицей. Затем проверьте, равна ли луна самой большой, чтобы напечатать «да» или «нет».

Вот пример использования MySQL. Я создал таблицу Moons, содержащую столбцы moonPlanetOrbited, bodyName, moonMeanRadius. Следующий SQL выбирает самый большой moonMeanRadius для данного moonPlanetOrbited:

SELECT moonPlantedOrbited, MAX(moonMeanRadius) as maxMoonRadius
FROM Moons
GROUP BY moonPlanetOrbitede

Теперь, когда у нас есть список maxMoonRadius, объедините результирующий набор со всей таблицей и проверьте, равен ли moonMeanRadius maxMoonRadius:

SELECT m1.moonPlanetOrbited, m2.bodyName,  
if(m1.moonMeanRadius = m2.maxMoonRadius, 'Yes', 'No') as Largest 
FROM Moons m1  
JOIN (   
  SELECT moonPlanetOrbited, MAX(moonMeanRadius) as maxMoonRadius   
  FROM Moons   
  GROUP BY moonPlanetOrbited 
) m2 
ON m1.moonPlanetOrbited = m2.moonPlanetOrbited;

Синтаксис IF взят из MySQL 5.5: http://dev.mysql.com/doc/refman/5.5/en/control-flow-functions.html#function_if

Протестировано с использованием следующего SQL:

CREATE TABLE Moons( 
  moonPlanetOrbited VARCHAR(255), 
  bodyName VARCHAR(255), 
  moonMeanRadius FLOAT
);

INSERT INTO Moons('a', 'b', 1.01);
INSERT INTO Moons('a', 'c', 1.02);
INSERT INTO Moons('a', 'd', 1.03);
INSERT INTO Moons('a', 'e', 1.04);


+-------------------+----------+---------+
| moonPlanetOrbited | bodyName | Largest |
+-------------------+----------+---------+
| a                 | b        | No      |
| a                 | c        | No      |
| a                 | d        | No      |
| a                 | e        | Yes     |
+-------------------+----------+---------+
4 rows in set (0.00 sec)
0 голосов
/ 06 августа 2010

Вот попытка (не проверенная), которая максимально приближена к вашему подходу, поскольку ваша идея была не так уж и далека:

Select 
M.moonPlanetOrbited, 
M.bodyName, 
CASE
  WHEN M.bodyName = 
    (SELECT top 1 bodyName from Body 
    where moonPlanetOrbited = M.moonPlanetOrbited 
    order by moonMeanRadius DESC) 
Then 'Y' 
Else 'N'
AS Largest
FROM body

Вам просто нужен был префикс таблицы, чтобы фактически сделать корреляцию скорневая таблица, а также чтобы убедиться, что вы сравнивали яблоки с яблоками в своем заявлении CASE.

0 голосов
/ 05 августа 2010

Вот мой синтаксис MS-SQL:

SELECT
  B.moonPlanetOrbited
  , B.bodyName
  , CASE
      WHEN B.bodyName = 
      (SELECT TOP 1
         iB.bodyName
       FROM
         Body AS iB
       WHERE
         iB.moonPlanetOrbited = B.bodyName
       ORDER BY
         iB.moonMeanRadius DESC
       )
       THEN 'Yes'
       ELSE 'No'
     END CASE AS [Largest]
FROM
 Body AS B

Если таблица использует идентификаторы в качестве первичного ключа, может быть лучше сравнить идентификаторы вместо имен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...