有两个SQL表:
Parents:
+--+---------+
|id| text |
+--+---------+
| 1| Blah |
| 2| Blah2 |
| 3| Blah3 |
+--+---------+
Childs
+--+------+-------+
|id|parent|feature|
+--+------+-------+
| 1| 1 | 123 |
| 2| 1 | 35 |
| 3| 2 | 15 |
+--+------+-------+
我想从Parents表中的每一行中选择单个查询,并从Childs表中选择每一行与“parent” - “id”值和最大“feature”列值的单行。在此示例中,结果应为:
+----+------+----+--------+---------+
|p.id|p.text|c.id|c.parent|c.feature|
+----+------+----+--------+---------+
| 1 | Blah | 1 | 1 | 123 |
| 2 | Blah2| 3 | 2 | 15 |
| 3 | Blah3|null| null | null |
+----+------+----+--------+---------+
其中p =父表和c =子表
我尝试LEFT OUTER JOIN和GROUP BY,但是MSSQL Express告诉我,GROUP BY的查询需要在每个非Groupped字段上使用Aggregate函数。而且我不想将它们全部分组,而是选择顶行(使用自定义排序)。
我完全没有想法......
答案 0 :(得分:17)
select p.id, p.text, c.id, c.parent, c.feature
from Parents p
left join (select c1.id, c1.parent, c1.feature
from Childs c1
join (select p1.id, max(c2.feature) maxFeature
from Parents p1
left join Childs c2 on p1.id = c2.parent
group by p1.id) cf on c1.parent = cf.id
and c1.feature = cf.maxFeature) c
on p.id = c.parent
答案 1 :(得分:9)
使用CTE(SQL Server 2005 +):
WITH max_feature AS (
SELECT c.id,
c.parent,
MAX(c.feature) 'feature'
FROM CHILD c
GROUP BY c.id, c.parent)
SELECT p.id,
p.text,
mf.id,
mf.parent,
mf.feature
FROM PARENT p
LEFT JOIN max_feature mf ON mf.parent = p.id
非CTE当量:
SELECT p.id,
p.text,
mf.id,
mf.parent,
mf.feature
FROM PARENT p
LEFT JOIN (SELECT c.id,
c.parent,
MAX(c.feature) 'feature'
FROM CHILD c
GROUP BY c.id, c.parent) mf ON mf.parent = p.id
您的问题缺乏处理断路器的详细信息(当2 + CHILD.id
值具有相同的特征值时)。 Agent_9191的答案使用了TOP 1
,但这将是第一个返回的&不一定是你想要的那个。
答案 2 :(得分:4)
这应该有效:
SELECT p.id, p.text, c.id, c.parent,c.feature
FROM parent p
LEFT OUTER JOIN (SELECT TOP 1 child.id,
child.parent,
MAX(child.feature)
FROM child
WHERE child.parent = p.id
GROUP BY child.id, child.parent
) c ON p.id = c.parent
答案 3 :(得分:3)
manji的查询不处理最大功能的断路器。这是我的方法,我已经测试过了:
;WITH WithClause AS (SELECT p.id, p.text,
(SELECT TOP 1 c.id from childs c
where c.parent = p.id order by c.feature desc)
AS BestChildID
FROM Parents p)
SELECT WithClause.id, WithClause.text, c.id, c.parent, c.feature
FROM WithClause
LEFT JOIN childs c on WithClause.BestChildID = c.id
答案 4 :(得分:1)
如果需要通过关闭嵌套选择来加入与MAX列不同的组以及组中描述的任何列,则可以使用APPLY函数。 这是一个最简单的解决方案。您也可以使用WITH运算符。但那看起来更难。
SELECT p.id, p.text, CHILD_ROW.ANY_COLLUMN
FROM parent p
OUTER APPLY (SELECT TOP 1 child.ANY_COLLUMN
FROM child
WHERE child.parent = p.id
ORDER BY child.feature DESC
) CHILD_ROW