有两个SQL表:
Parents:
+--+---------+
|id| text |
+--+---------+
| 1| Blah |
| 2| Blah2 |
| 3| Blah3 |
+--+---------+
Childs
+--+------+-------+
|id|parent|feature|
+--+------+-------+
| 1| 1 | 123 |
| 2| 1 | 35 |
| 3| 2 | 15 |
+--+------+-------+
我想用单一的查询选择从父母表,从表童车每一个单行关系“父”的每一行 - “ID”值和最大的“功能”列的值。 在这个例子的结果应该是:
+----+------+----+--------+---------+
|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快告诉我,GROUP BY该查询要求对每一个非细分电子邮件域聚合函数。 我不希望他们全部归类,而是选择最上面一行(自定义排序)。
我完全没了主意......
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
使用CTE(SQL服务器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
,但会第一时间被返回&不一定是你想要的。
这应该工作:
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
满级的查询不处理领带断路器的最大特点。 这里是我的方法,我已经测试过:
;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
如果您需要加入从MAX列并通过嵌套选择关闭一组中描述的任何列的不同,你可以使用一个应用函数。 这是一个简单的解决方案。 您也可以通过运营商使用。 但是,这看起来更难。
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
文章来源: one-to-many query selecting all parents and single top child for each parent