SQL:如何根据条件选择第一个元素?
我有一个数据库,其中存储了关于基于日期执行的操作的多个信息,例如,我有以下行SQL:如何根据条件选择第一个元素?,sql,Sql,我有一个数据库,其中存储了关于基于日期执行的操作的多个信息,例如,我有以下行 "John", "Action1, "2017-02-20" "John", "Action2, "2017-02-10" "Mark", "Action3", "2016-09-21" "Mark", "Action4", "2016-03-11" 如果我想为每个用户返回最新的活动(John Action1,Mark Action3),我可以使用SQL语句,还是需要在SQL语句返回所有值后在源代码中过滤它 它是Po
"John", "Action1, "2017-02-20"
"John", "Action2, "2017-02-10"
"Mark", "Action3", "2016-09-21"
"Mark", "Action4", "2016-03-11"
如果我想为每个用户返回最新的活动(John Action1,Mark Action3),我可以使用SQL语句,还是需要在SQL语句返回所有值后在源代码中过滤它
它是Postgres DB
谢谢执行此操作的典型方法是使用
行编号()
:
row\u number()
几乎是所有数据库中可用的ANSI标准函数。执行此操作的典型方法是使用row\u number()
:
row\u number()
是一个ANSI标准函数,几乎可以在所有数据库中使用。这应该可以使用
---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]
这应该行得通
---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]
我刚刚在postgres实例上运行了以下内容-希望它在良好的ANSI SQL中运行,并且应该在其他db中运行:
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中(具有可选的额外表和列别名):
这样做的目的是将您的表连接到其自身的聚合版本,并获取额外的信息(action
)。这些可选的额外列和表别名可能更容易查看发生了什么
请注意,在这个典型的groupby
语句中,对于带有聚合函数的SELECT
语句(MAX()
,在本例中),您应该groupby
所有非聚合列(在本例中只有一个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)
是的,看起来还可以]我刚刚在一个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中(具有可选的额外表和列别名):
这样做的目的是将您的表连接到其自身的聚合版本,并获取额外的信息(action
)。这些可选的额外列和表别名可能更容易查看发生了什么
请注意,在这个典型的groupby
语句中,对于带有聚合函数的SELECT
语句(MAX()
,在本例中),您应该groupby
所有非聚合列(在本例中只有一个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)
是的,看起来还可以]您使用的是哪种数据库管理系统?答案可能是特定于产品的。最后一个字段是一个真实日期,或者只是一个字符串。如果用户在第一个日期有两个不同的操作,则返回什么?您使用的是哪种dbms?答案可能是特定于产品的。最后一个字段是一个真实的日期,或者只是一个字符串。如果用户在第一个日期有两个不同的操作,则返回什么?很漂亮!非常感谢你!美丽的!非常感谢你!