如何在SQL查询中将行数限制为一个唯一的行?

如何在SQL查询中将行数限制为一个唯一的行?,sql,sql-server,Sql,Sql Server,我需要在SQL查询中将行号限制为一个唯一的行。下面是识别我所说内容的示例数据: john doe 3000 fog horn drive , ky 40444 john doe 3001 merry lane , ky 40484 我想返回列表中的第一个,这是我的查询: Select DISTINCT p.personID, e.citizenship, rtrim(i.lastname + CASE WHEN i.suffix IS NULL THEN '' ELSE '

我需要在SQL查询中将行号限制为一个唯一的行。下面是识别我所说内容的示例数据:

john doe 3000 fog horn drive , ky 40444
john doe 3001 merry lane , ky 40484
我想返回列表中的第一个,这是我的查询:

Select 
    DISTINCT p.personID, e.citizenship, 
    rtrim(i.lastname + CASE WHEN i.suffix IS NULL THEN '' ELSE ' ' + i.suffix END) + ', ' + i.firstname + (CASE WHEN i.middlename IS NULL THEN '' ELSE ' ' + i.middlename END) StuName, 
    e.grade, i.gender, p.studentNumber, e.citizenship, e.adult, i.birthdate, 
    e.disability1, e.disability2, ad.city, e.displacedHomemaker, e.homeSchooled, 
    e.localStudentNumber, e.migrant, e.modifiedDate, e.modifiedByID,
    rtrim(Staff.lastname + CASE WHEN Staff.suffix IS NULL THEN '' ELSE ' ' + Staff.suffix END) + ', ' + Staff.firstname + (CASE WHEN Staff.middlename IS NULL THEN '' ELSE ' ' + Staff.middleName END) Staffname, 
    Staff.personID Staffid, i.lastname, i.firstname, i.middlename, i.ssn, 
    ad.phone, ad.state, ad.zip, ad.addressLine1
FROM 
    Person p 
LEFT join 
    Enrollment e ON e.personID = p.personID And isnull(e.noshow, 0) = 0 
LEFT join 
    EnrollmentKY ky ON ky.enrollmentID = e.enrollmentID 
LEFT join 
    [Identity] i ON i.identityID = p.currentIdentityID And i.personID = p.personID 
INNER join 
    Calendar c ON c.calendarID = e.calendarID 
INNER join 
    SchoolYear sy ON sy.endYear = c.endYear AND sy.active = 1 
JOIN 
    staffMember Staff ON Staff.personID = e.modifiedByID 
--join view_students s ON  s.personID = i.personID
left join 
    v_MailingAddress ad ON ad.personID = i.personID And ad.relatedBy = 'household'
                        And ad.endDate IS NULL And isnull(ad.secondary, 0) = 0 
order by 
    i.lastname, i.firstname, i.middlename

编辑:只需要选择SQL代码中的第一行,因为我对有多个地址的人有问题,它会为他们放置两行,并且我只需要有多个地址的人的第一行数据。

编辑:删除原始答案,因为问题已更改,原始答案不是更改问题的方式


根据Neil Hoskins建议按子句分组。

尝试使用
限制来限制输出的数量

例如:

您是否尝试过使用“GROUPBY”子句而不是DISTINCT关键字


还有,子查询呢?如果我在写这种类型的东西,我会使用存储过程并创建一个临时表。

如果每个记录的
personId是不同的,并且它们只是有不同的地址,那么您可以为
行编号()添加一个字段
,然后只选择
行编号=1的记录:

select *
from 
(
  Select p.personID,
    e.citizenship, 
    rtrim(i.lastname + CASE WHEN i.suffix IS NULL THEN '' ELSE ' ' + i.suffix END) + ', ' + i.firstname + (CASE WHEN i.middlename IS NULL THEN '' ELSE ' ' + i.middlename END) StuName, 
    e.grade, 
    i.gender, 
    p.studentNumber, 
    e.citizenship, 
    e.adult, 
    i.birthdate, 
    e.disability1, 
    e.disability2, 
    ad.city, 
    e.displacedHomemaker, 
    e.homeSchooled,
    e.localStudentNumber,
    e.migrant,
    e.modifiedDate,
    e.modifiedByID,
    rtrim(Staff.lastname + CASE WHEN Staff.suffix IS NULL THEN '' ELSE ' ' + Staff.suffix END) + ', ' + Staff.firstname + (CASE WHEN Staff.middlename IS NULL THEN '' ELSE ' ' + Staff.middleName END) Staffname, 
    Staff.personID Staffid,
    i.lastname, 
    i.firstname, 
    i.middlename,
    i.ssn, 
    ad.phone, 
    ad.state, 
    ad.zip, 
    ad.addressLine1,
    row_number() over(partition by p.personid order by p.personid) rn -- add this field
  FROM Person p 
  LEFT join Enrollment e 
    ON e.personID = p.personID 
    And isnull(e.noshow,0)=0 
  LEFT join EnrollmentKY ky 
    ON ky.enrollmentID = e.enrollmentID 
  LEFT join [Identity] i 
    ON i.identityID = p.currentIdentityID 
    And i.personID = p.personID 
  INNER join Calendar c 
    ON c.calendarID = e.calendarID 
  INNER join SchoolYear sy 
    ON sy.endYear = c.endYear 
    AND sy.active = 1 
  JOIN staffMember Staff 
    ON Staff.personID = e.modifiedByID 
  --join view_students s ON  s.personID = i.personID
  left join v_MailingAddress ad 
    ON ad.personID = i.personID 
    And ad.relatedBy = 'household'
    And ad.endDate IS NULL 
    And isnull(ad.secondary,0)=0 
) x
where x.rn = 1
order by x.lastname, x.firstname, x.middlename

@拉马克,OP要求返回一行。选择Top1返回一行。关于OP将如何决定返回哪一行,我和蓝足有相同的问题,但我们没有这些信息。我想也许我们可以讨论一下。我认为我不值得投反对票。如果你有答案,为什么不把它放在那里呢?请看上面的编辑我更新了信息,表示每个人都有一行唯一的数据。“而且,我也试过这样做,因为这与我的需要无关。”“杰弗里:好吧,这是一个完全不同的问题。如果这就是你想要的,那么尼尔·霍斯金斯很可能会建议他的团队。@mikeY-否决票是一种表达当我觉得答案没有用处时的方式(正如工具提示所说),我不需要提供答案。事实上,我甚至不需要留下评论,但我留下了,但我想这是一个错误,因为现在我有两个“匿名”用户对其他答案投了反对票。只有只读和执行权限,所以这是不可能的。不过我会尝试使用group by子句。再次检查这个有用的提示,但到目前为止似乎仍然有效。它有效,只提取一个地址,但我认为为一个人输入数据的人会输入两个主地址。所以我认为这应该归咎于做数据录入的人。感谢您将订单更改为x.lastname等等,这将适用于任何查看此线程的人。
select *
from 
(
  Select p.personID,
    e.citizenship, 
    rtrim(i.lastname + CASE WHEN i.suffix IS NULL THEN '' ELSE ' ' + i.suffix END) + ', ' + i.firstname + (CASE WHEN i.middlename IS NULL THEN '' ELSE ' ' + i.middlename END) StuName, 
    e.grade, 
    i.gender, 
    p.studentNumber, 
    e.citizenship, 
    e.adult, 
    i.birthdate, 
    e.disability1, 
    e.disability2, 
    ad.city, 
    e.displacedHomemaker, 
    e.homeSchooled,
    e.localStudentNumber,
    e.migrant,
    e.modifiedDate,
    e.modifiedByID,
    rtrim(Staff.lastname + CASE WHEN Staff.suffix IS NULL THEN '' ELSE ' ' + Staff.suffix END) + ', ' + Staff.firstname + (CASE WHEN Staff.middlename IS NULL THEN '' ELSE ' ' + Staff.middleName END) Staffname, 
    Staff.personID Staffid,
    i.lastname, 
    i.firstname, 
    i.middlename,
    i.ssn, 
    ad.phone, 
    ad.state, 
    ad.zip, 
    ad.addressLine1,
    row_number() over(partition by p.personid order by p.personid) rn -- add this field
  FROM Person p 
  LEFT join Enrollment e 
    ON e.personID = p.personID 
    And isnull(e.noshow,0)=0 
  LEFT join EnrollmentKY ky 
    ON ky.enrollmentID = e.enrollmentID 
  LEFT join [Identity] i 
    ON i.identityID = p.currentIdentityID 
    And i.personID = p.personID 
  INNER join Calendar c 
    ON c.calendarID = e.calendarID 
  INNER join SchoolYear sy 
    ON sy.endYear = c.endYear 
    AND sy.active = 1 
  JOIN staffMember Staff 
    ON Staff.personID = e.modifiedByID 
  --join view_students s ON  s.personID = i.personID
  left join v_MailingAddress ad 
    ON ad.personID = i.personID 
    And ad.relatedBy = 'household'
    And ad.endDate IS NULL 
    And isnull(ad.secondary,0)=0 
) x
where x.rn = 1
order by x.lastname, x.firstname, x.middlename