我试图从包含子字段的每个父行的子表中只获取一行,我一直尝试使用GRUOP BY但没有成功:(这是我的初始SELECT
SELECT pID, lastname
FROM parent
LEFT JOIN
(SELECT cID, pID, phone, company, title FROM child) as child
ON parent.pID = child.pID
Run Code Online (Sandbox Code Playgroud)
这是表格结构
CREATE TABLE parent (
pID Counter(1,1) PRIMARY KEY,
firstname VarChar(24) DEFAULT '',
lastname VarChar(20) DEFAULT ''
);
CREATE TABLE child (
cID Counter(1,1) PRIMARY KEY,
pID int DEFAULT '0',
phone VarChar(16) DEFAULT '',
company VarChar(24) DEFAULT '',
title VarChar(24) DEFAULT '',
address TEXT
);
Run Code Online (Sandbox Code Playgroud)
"对于包含子字段的每个父行,只从子表中获取一行"
听起来这个child表可以有相同pID值的多行.而且child每个只需要一行pID.
SELECT pID, Min(cID) AS MinOfcID
FROM child
GROUP BY pID;
Run Code Online (Sandbox Code Playgroud)
再次将该GROUP BY查询加入child表中,以检索每个目标值的其他列cID.将此查询另存为qryChild.
SELECT
c.pID,
c.cID,
c.phone,
c.company,
c.title,
c.address
FROM
(
SELECT pID, Min(cID) AS MinOfcID
FROM child
GROUP BY pID
) AS map
INNER JOIN child AS c
ON c.cID = map.MinOfcID;
Run Code Online (Sandbox Code Playgroud)
最后,要包含lastname值,请将parent表连接到qryChild.
您没有说明您的 DBMS,所以这是一个标准的 ANSI 解决方案:
SELECT pID, lastname
FROM parent
LEFT JOIN (
SELECT pID,
row_number() over (partition by pid order by cid) as rn
FROM child
) as child
ON parent.pID = child.pID and child.rn = 1
Run Code Online (Sandbox Code Playgroud)
您将哪些行定义为“第一”行取决于您。除非您对行进行排序,否则没有“第一”行之类的 - 这就是该部分order by cid在分区子句中所做的。因此,如果您想要与“第一”行不同的内容,则需要更改它。
顺便说一句:如果您不使用它们,则无需从子表中选择所有列。