我的数据库上有一张表,记录了员工全天的每次通话。
每条记录都是分支线的调用。
如果一个分支机构每天拨打50个电话,我们将在DB上有50条记录:
branch | date
-------+----------------------------
72489 | 2015-12-03 08:03:58
34002 | 2015-12-03 08:03:59
78700 | 2015-12-03 08:05:37
78700 | 2015-12-03 08:05:53
78700 | 2015-12-03 08:05:57
78700 | 2015-12-03 08:06:24
我想做的是接听每个支线的第一天电话。
我尝试使用DISTINCT:
SELECT DISTINCT branch, date FROM table WHERE date::date='2015-12-03'::date;
据说DISTINCT会避免在分支上重复,但结果是:
branch | date
-------+----------------------------
34002 | 2015-12-03 07:58:24
34002 | 2015-12-03 08:00:40
59754 | 2015-12-03 08:01:31
34002 | 2015-12-03 08:01:56
59754 | 2015-12-03 08:02:09
57764 | 2015-12-03 08:02:17
59754 | 2015-12-03 08:02:28
我在那里有一些重复。
我喜欢的结果是:
branch | date
-------+----------------------------
34002 | 2015-12-03 07:58:24
59754 | 2015-12-03 08:01:31
59754 | 2015-12-03 08:02:09
我尝试使用GROUP BY:
SELECT branch, date FROM table WHERE date::date='2015-12-03'::date GROUP BY branch;
但是得到这个错误:
错误:列“table.date”必须出现在GROUP BY子句中或用于聚合函数。
有人可以帮我吗?
PS:对不起英文,我的不好。
答案 0 :(得分:1)
使用::date
进行演员表示您正在使用Postgres。在这种情况下,使用distinct on()
运算符来获取“每个分支行的第一天调用”非常简单:
SELECT DISTINCT ON (branch) branch, date
FROM table
WHERE date::date = '2015-12-03'::date
ORDER BY branch, date;
解决此类查询的另一种可能性是使用窗口函数:
select branch, date
from (
select branch, date,
row_number() over (partition by branch order by date) as rn
where cast(date as date) = date '2015-12-03'
) t
where rn = 1
order by branch;
distinct on ()
解决方案是Postgres特有的,第二个解决方案是ANSI SQL(使用ANSI日期文字和ANSI转换)
答案 1 :(得分:0)
可能的解决方案:
SELECT
branch,
(
select
date
from
table tb
where
tb.branch = table.branch
) as date
FROM
table
GROUP BY
branch
WHERE
date::date='2015-12-03'::date;
答案 2 :(得分:0)
只要同一日期的其他行不在之前,就选择一行:
SELECT branch, date
FROM table t1
WHERE not exists (select 1 from table t2
where cast(t1.date as date) = cast(t2.date as date)
and t2.date < t1.date)
ANSI SQL兼容。