按姓氏和身份排序

时间:2015-01-10 16:20:55

标签: sql sql-server sql-server-2008

我有两个数据库表

 FAMILY
 ------
 family_id (PK)
 address
 ....

 PERSON
 -----
 person_id (PK)
 lastname
 birthday
 family_id (FK)
 family_role (numeric >1 male, 2 female, 3 male(child), 4 female(child)
 ....

我想创建一个字母系列列表,其中最老的人的姓氏必须由FAMILY_ROLE引导和排序。我正在尝试这样的事情:

 select *
 from person, family
 where person.family_id = family.family_id
 order by lastname, family_role

现在这不起作用,因为同一家族中的姓氏不一定相同。所以这是有效的

 select *
 from person, family
 where person.family_id = family.family_id
 order by family_id, family_role

但这并没有给我一个字母列表。 输出必须是:

 Test street 1 - New York (family_id = 100)
 John Bla (family_id = 100 | person_id =10 | family_role=1) 
 Sara Bla (family_id = 100 | person_id =13 | family_role=2)
 ----
 Apple street 1 - New York (family_id = 45)
 Rick Cha (family_id = 45 | person_id =1 | family_role=1)
 Lin Cha (family_id = 45 | person_id =5 | family_role=2)
 Jean App (family_id = 45 | person_id =3 | family_role=4)
 ----
 Cherry street 114 - New York (family_id = 23)
 Becky Cha (family_id = 23 | person_id =122 | family_role=2)
 ----

有人能帮助我吗?数据库版本MSSQL 2008。

另请注意,人们可以使用相同的姓氏,但属于不同的家庭(请参阅输出示例中的Cha系列)。

谢谢!

2 个答案:

答案 0 :(得分:1)

您需要一种方法将家庭中最老的人的姓氏与家庭中的每个人相关联。您可以在cte /子查询中使用ROW_NUMBER()

;with cte AS (SELECT *,ROW_NUMBER() OVER(PARTITION BY Family_ID ORDER BY Age DESC) AS RN
              FROM Person
              )
 SELECT p.*,f.*
 FROM person p
 JOIN family f
   ON p.family_id = f.family_id
 JOIN cte 
   ON p.family_id = cte.Family_ID
   AND cte.RN = 1
 ORDER BY cte.lastname

ROW_NUMBER()函数为每一行分配一个数字。 PARTITION BY是可选的,但用于为该组中的每个值开始编号,即:如果您PARTITION BY Family_ID,那么对于每个唯一Family_ID值,编号将从1开始。{ {1}}当然用于定义计数应该如何进行,并且在ORDER BY函数中是必需的。

因此,cte / subquery为您提供了一种方法,可以查看最早的人是谁并在一个步骤中访问他们的姓氏,然后您可以ROW_NUMBER()JOIN中使用它。

注意:也应该避免旧式连接,所以我也更新了,我假设你的ORDER BY表中有一个Age字段来确定最老的是谁,Person可能需要根据实际的表格结构进行更新。

答案 1 :(得分:0)

那么,您必须决定如何选择哪个家庭成员来确定家庭的字母位置。例如,如果家庭#100有Jon Doe和Jane Smith,它会按字母顺序排在Ds还是Ss?

您可以像这样编写查询

SELECT f.*,p.*,A.FamilyNameOrderKey FROM 
    (
    SELECT 
          Min(lastname) As FamilyNameOrderKey, Family_id
    FROM
          person
    Group by Family_id
    ) As A
INNER JOIN
    family f
ON
    A.family_id = f.family_id
INNER JOIN
    people p
ON
   p.family_id = f.family_id
    )

由A.FamilyNameOrderKey订购 这将按每个家庭中按字母顺序排列的姓氏的姓氏进行排序