5

我试图从包含子字段的每个父行的子表中只获取一行,我一直在尝试使用 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

这是表格结构

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
);
4

4 回答 4

13

“对于包含子字段的每个父行,仅从子表中获取一行”

这听起来像child表可以有不止一行相同的pID值。而且您只希望child每个pID.

SELECT pID, Min(cID) AS MinOfcID
FROM child
GROUP BY pID;

再次将该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;

最后,要包含lastname值,请将parent表连接到qryChild.

于 2012-05-07T11:07:11.497 回答
6

您没有说明您的 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

您将哪些行定义为“第一”行取决于您。除非您对行进行排序,否则没有诸如“第一”行之类的行 - 这就是该部分order by cid在分区子句中所做的事情。因此,如果您想要与“第一”行不同的东西,则需要对其进行更改。

顺便说一句:如果您不使用子表,则无需从子表中选择所有列。

于 2012-05-07T09:07:29.240 回答
0

你必须更换

SELECT cID, pID, phone, company, title FROM child

每个pid只返回一行。正确的选择取决于您的要求。简单的是group by

SELECT min(cID), pID, min(phone), min(company), min(title) FROM child group by cID

但是不同的列将来自不同的行,因此您可能想要“第一行”之类的内容,这取决于您使用的 RDBMS,因此请将该信息添加到您的问题中。

于 2012-05-07T09:04:47.283 回答
0
SELECT cID ChildID, 
       pID ParentID, 
       phone, 
       company, 
       title, 
       (SELECT lastname FROM parent WHERE id = ParentID) as LastName
FROM child
GROUP BY ParentID
于 2012-05-07T09:11:54.990 回答