如何在视图中为新列使用相关子查询?

时间:2010-08-05 19:16:58

标签: sql views alias correlated-subquery

我正在尝试编写一个包含3列的视图:Planet,Moon和Largest。

该视图旨在显示行星,它们的卫星以及是或否的列,表明它是否是地球上最大的卫星。

只使用了一个Basetable,我引用的列是moonPlanetOrbit(如果bodyType ='月亮',则不为null),bodyName(月亮名称)和最大值('yes'或'no')

到目前为止,这是我的尝试:

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 个答案:

答案 0 :(得分:1)

SQL最适合数据集。我的建议是使用SELECT语句和MAX()函数获取最大的卫星集,然后将结果集与整个表连接起来。然后测试月亮是否等于最大值以打印“是”或“否”。

以下是使用MySQL的示例。我创建了一个包含moonPlanetOrbited,bodyName,moonMeanRadius列的表Moons。以下SQL为给定的moonPlanetOrbited选择最大的moonMeanRadius:

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)

答案 1 :(得分:0)

这是我的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

如果表使用ID作为主键,那么比较ID而不是名称可能更好。

答案 2 :(得分:0)

这是一种尽可能接近你的方法的尝试(未经测试),因为你的想法并不遥远:

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语句中比较苹果与苹果。