嵌套的Sql select语句

时间:2014-05-03 13:55:58

标签: sql sql-server

有人能告诉我以下sql查询有什么问题吗?

Select *, 
(SELECT [DiseaseID], COUNT(*) AS [Rank] FROM [DiseaseSymptom] WHERE
    ([SymptomID] IN(1, 5)) GROUP BY [DiseaseID] ORDER BY [Rank] DESC)
FROM Disease WHERE GenderID in (1, 3)

我有2个表,其中包含疾病和与之相关的性别

疾病

+-----------+-------------------+----------+
| DiseaseID |    DiseaseName    | GenderID |
+-----------+-------------------+----------+
|         1 | Fever             |        3 |
|         2 | Flu               |        3 |
|         3 | Lady Disease      |        2 |
|         4 | Gentlemen Disease |        1 |
+-----------+-------------------+----------+

性别1 =男性,2 =女性,3 =普通

像这样的症状疾病矩阵

DiseaseSymptom

+-----------+-----------+----------+
| DiseaseID | SymptomID | DissymID |
+-----------+-----------+----------+
|         1 |         1 |        1 |
|         1 |         2 |        3 |
|         1 |         4 |        4 |
|         2 |         1 |        5 |
|         2 |         3 |        9 |
|         2 |         4 |        6 |
|         2 |         5 |        7 |
+-----------+-----------+----------+

我从用户那里得到症状并在DiseaseSymptom表中进行匹配,并根据匹配的症状数量对其进行排名(内部sql语句)

在外部声明中,我只想从内部声明中获取结果并评估它是否属于特定性别。我尝试运行上述查询时得到的错误是

The ORDER BY clause is invalid in views, inline functions, derived tables, subqueries, and common table expressions, unless TOP or FOR XML is also specified.

4 个答案:

答案 0 :(得分:0)

您正在使用带有group by的子查询。你的意图是有一个相关的子查询。问题是子查询返回多行。我想这就是你想要的:

Select d.*, 
      (SELECT COUNT(*) AS [Rank]
       FROM [DiseaseSymptom] ds
       WHERE [SymptomID] IN (1, 5)) AND ds.DiseaseId = d.DiseaseId
      )
FROM Disease d
WHERE GenderID in (1, 3);

答案 1 :(得分:0)

select子句中的子查询必须只生成标量值,而不是具有多个列或行的结果集。如果你想要两个然后将子查询放在from子句中(正确相关),并参考select子句中的两个不同的vqlues

 Select d.*, z.DeseaseId, z.Rank
 FROM Disease d
     join (SELECT DiseaseID, COUNT(*) Rank
           FROM DiseaseSymptom
           WHERE SymptomID IN(1, 5) 
           GROUP BY DiseaseID) Z
       On z.DeseaseId = d.DeseaseId
 WHERE GenderID in (1, 3)
 Order By z.Rank

答案 2 :(得分:0)

你应该像这样使用Common Table Expression(cte):

    with cte as (SELECT [DiseaseID], GenderID, COUNT(*) AS [Rank] FROM [DiseaseSymptom] WHERE
    ([SymptomID] IN(1, 5)) GROUP BY [DiseaseID],GenderID ORDER BY [Rank] DESC)
    select * FROM cte WHERE GenderID in (1, 3)

希望这个帮助;)

答案 3 :(得分:0)

实际上不需要嵌套查询,只需加入和过滤

SELECT d.DiseaseID, d.DiseaseName, d.GenderID
     , Symptoms = Count(ds.SymptomID)
FROM   Disease d
       INNER JOIN DiseaseSymptom ds ON d.DiseaseID = ds.DiseaseID
WHERE  ds.SymptomID IN (1, 5)
  AND  d.GenderID IN (1, 3)
GROUP BY d.DiseaseID, d.DiseaseName, d.GenderID
ORDER BY Count(SymptomID) Desc

SQLFiddle演示