SQL在1列中选择唯一值

时间:2010-02-21 21:15:19

标签: sql

我有问题(我想有点问题),我希望,你会帮助我。 我使用Sybase Anywhere,这是我的代码:

SELECT TOP 4 Person.Id_person, Person.Name, Person.Surname, Visit.Date, Visit.Place
From Person, Visit
WHERE Visit.Id_person = Person.Id_person
ORDER BY Visit.DATE DESC

这是结果:

3  | Paul | McDonald | 2010-01-19 | Ohio
3  | Paul | McDonald | 2010-01-18 | New York
19 | Ted  | Malicky  | 2009-12-24 | Tokyo
12 | Meg  | Newton   | 2009-10-13 | Warsaw

我不想复制保罗麦克唐纳,并且只有第一次(按日期)访问。我想得到这样的结果:

3  | Paul | McDonald | 2010-01-19 | Ohio
19 | Ted  | Malicky  | 2009-12-24 | Tokyo
12 | Meg  | Newton   | 2009-10-13 | Warsaw
 ....

我该怎么办?你可以帮帮我吗? :(

3 个答案:

答案 0 :(得分:4)

这是使用ROW_NUMBER函数执行此操作的另一种方法,以确保如果有人在同一天有两次会议,它仍然有效:

SELECT TOP 4
    Person.Id_person,
    Person.Name,
    Person.Surname,
    T1.Date,
    T1.Place
FROM
    (SELECT
        *,
        ROW_NUMBER() OVER (PARTITION BY Id_person ORDER BY Date DESC) AS rn
    FROM Visit) AS T1
JOIN Person
ON T1.Id_person = Person.Id_person
WHERE rn = 1
ORDER BY Date DESC

这是我得到的结果:

Id_person Name Surname  Date       Place
3         Paul McDonald 2010-01-19 Ohio
19        Ted  Malicky  2009-12-24 Tokyo
12        Meg  Newton   2009-10-13 Warsaw
1         Foo  Bar      2009-06-03 Someplace

这是我使用的测试数据:

CREATE TABLE Person (Id_person INT NOT NULL, Name NVARCHAR(100) NOT NULL, Surname NVARCHAR(100) NOT NULL);
INSERT INTO Person (Id_person, Name, Surname) VALUES
(3, 'Paul', 'McDonald'),
(19, 'Ted', 'Malicky'),
(12, 'Meg', 'Newton'),
(1, 'Foo', 'Bar'),
(2, 'Baz', 'Qux');

CREATE TABLE Visit (Id_person INT NOT NULL, Date DATE NOT NULL, Place NVARCHAR(100) NOT NULL);
INSERT INTO Visit (Id_person, Date, Place) VALUES
(3, '2010-01-19', 'Ohio'),
(3, '2010-01-18', 'New York'),
(19, '2009-12-24', 'Tokyo'),
(12, '2009-10-13', 'Warsaw'),
(1, '2009-06-03', 'Someplace'),
(12, '2009-10-13', 'Anotherplace'),
(2, '2009-05-04', 'Somewhere');

在SQL Server 2008上测试过,但我相信Sybase的语法类似。

答案 1 :(得分:3)

有一种更简单的方法,它也会向您展示每个人最近的行程:

SELECT TOP 4 Person.Id_person, Person.Name, Person.Surname, Visit.Date, Visit.Place 
  From Person, Visit 
  WHERE Visit.Id_person = Person.Id_person 
      AND (Visit.[Date] = (Select Max([Date]) 
                            From Visit Where (Person.Id_person=Visit.Id_Person)))
  ORDER BY Visit.DATE DESC

我在工作中经常使用这种变体。唯一需要注意的是访问表中的“日期”字段是DateTime(当然,有人不能同时在两个地方)。

答案 2 :(得分:1)

您可以添加where not exists子句来过滤掉之前的访问次数:

SELECT TOP 4 p1.Id_person, p1.Name, p1.Surname, v1.Date, v1.Place
FROM Person p1, Visit v1
WHERE p1.Id_person = v1.Id_person
AND NOT EXISTS (
    SELECT *
    From Person p2, Visit v2
    WHERE v2.Id_person = p2.Id_person
    AND p1.Id_person = p2.Id_person
    AND v2.Date > v1.Date
)
ORDER BY v1.DATE DESC

为了提高可读性,请考虑将双from重写为连接。例如,更改:

FROM Person v1, Visit v1
WHERE v1.Id_person = p1.Id_person

成:

FROM Person p1
INNER JOIN Visit v1 ON v1.Id_person = p1.Id_person