2017-02-20 59 views
-2

我在哪裏存儲若干個信息有關的行動進行基於日期,因此,例如我有以下行SQL:如何根據條件選擇第一個元素?

"John", "Action1, "2017-02-20" 
"John", "Action2, "2017-02-10" 
"Mark", "Action3", "2016-09-21" 
"Mark", "Action4", "2016-03-11" 

如果我想返回最近的活動每個用戶(DB約翰措施1 ,馬克行動3),我可以做一個SQL語句,或者我需要過濾在我的源代碼中,一旦SQL語句返回了所有的值?

它的一個Postgres數據庫

感謝

+0

哪個DBMS您使用的?答案可能是產品特定的。 – jarlh

+0

也是最後一個字段一個真正的日期,或只是一個字符串。 – SaggingRufus

+0

如果在第一次約會中有兩種不同的用戶操作,返回什麼? – jarlh

回答

2

這樣做的典型方式是使用row_number()

select t.* 
from (select t.*, 
      row_number() over (partition by col1 order by col3 desc) as seqnum 
     from t 
    ) t 
where seqnum = 1; 

row_number()在幾乎所有的數據庫提供的ANSI標準功能。

+0

美麗!非常感謝! –

1

這應該工作。

---sample data 
WITH mytable([name], [action], [date]) AS 
    (SELECT 'John', 
      'Action1', 
      '2017-02-20' 
    UNION ALL SELECT 'John', 
        'Action2', 
        '2017-02-10' 
    UNION ALL SELECT 'Mark', 
        'Action3', 
        '2016-09-21' 
    UNION ALL SELECT 'Mark', 
        'Action4', 
        '2016-03-11') 
---actual query 

SELECT t.[name], 
     mt.[action] 
FROM 
    (SELECT [name], 
      MAX([date]) AS [date] 
    FROM [mytable] 
    GROUP BY [name]) t 
INNER JOIN [mytable] mt ON t.[name] = mt.[name] 
AND t.[date] = mt.[date] 
0

我只是運行一個Postgres實例如下 - 希望它在良好的ANSI SQL,應當在其他分貝的工作:

SELECT ac.name, ac.action, ac.time 
FROM action_times ac 
JOIN (SELECT name, MAX(time) AS time 
    FROM action_times GROUP BY name) mx 
USING (name, time); 

其中給出:

name | action | time 
------+---------+------------ 
Mark | Action3 | 2016-09-21 
John | Action1 | 2017-02-20 
(2 rows) 

在舊式SQL(帶有可選的額外表格和列別名):

SELECT ac.name, ac.action, ac.time 
FROM action_times ac, 
(SELECT tmp.name AS max_name, MAX(tmp.time) AS max_time 
    FROM action_times tmp GROUP BY tmp.name) mx 
WHERE ac.name = mx.max_name 
AND ac.time = mx.max_time; 

這個想法是加入你的表到它自己的聚合版本,並獲得額外的信息(在這種情況下爲action)。這些可選的額外列和表別名可能會讓您更容易看到發生了什麼。

注意,在一個SELECT語句聚合函數這個典型GROUP BYMAX()在這種情況下),你應該GROUP BY所有的非聚集列(只有一個人,name,在這種情況下)。

[設置的東西: -

create table action_times (name varchar(10), action varchar(10), time varchar(10)); 
insert into action_times values ('John', 'Action1', '2017-02-20'); 
insert into action_times values ('John', 'Action2', '2017-02-10'); 
insert into action_times values ('Mark', 'Action3', '2016-09-21'); 
insert into action_times values ('Mark', 'Action4', '2016-03-11'); 

快速檢查:確定

select * from action_times order by name, time; 
name | action | time 
------+---------+------------ 
John | Action2 | 2017-02-10 
John | Action1 | 2017-02-20 
Mark | Action4 | 2016-03-11 
Mark | Action3 | 2016-09-21 
(4 rows) 

燁,看起來]