我有一张下列日期表:
dateID INT (PK),
personID INT (FK),
date DATE,
starttime VARCHAR, --Always in a format of 'HH:MM'
我想要做的是我想为每个人提取最低日期(主要条件)和开始时间(次要条件)的行(所有列,包括PK)。例如,如果我们有
row1(date ='2013-04-01'和starttime = '14:00')
和
row2(date ='2013-04-02'和starttime = '08:00')
将检索row1以及所有其他列。
到目前为止,我已经提出了逐步过滤表格,但它非常混乱。有更有效的方法吗?
这是我到目前为止所做的:
SELECT
D.id
, D.personid
, D.date
, D.starttime
FROM table D
JOIN (
SELECT --Select lowest time from the subset of lowest dates
A.personid,
B.startdate,
MIN(A.starttime) AS starttime
FROM table A
JOIN (
SELECT --Select lowest date for every person to exclude them from outer table
personid
, MIN(date) AS startdate
FROM table
GROUP BY personid
) B
ON A.personid = B.peronid
AND A.date = B.startdate
GROUP BY
A.personid,
B.startdate
) C
ON C.personid = D.personid
AND C.startdate = D.date
AND C.starttime = D.starttime
它有效,但我认为有一种更干净/有效的方法。有什么想法吗?
编辑:让我扩展一个问题 - 我还需要为每个人提取最长日期(只有日期,没有时间)。
结果应如下所示:
id
personid
max(date) for each person
min(date) for each person
min(starttime) for min(date) for each person
它是一个更大的查询的一部分(结果表与它连接),结果表必须足够轻量级,以便查询不会执行太长时间。使用此表的单个连接(仅对我想要的每个字段使用min,max),查询花了大约3秒钟,我希望生成的查询不会超过2-3倍。
答案 0 :(得分:3)
你应该能够这样做:
select a.dateID, a.personID, a.date, a.max_date, a.starttime
from (select t.*,
max(t.date) over (partition by t.personID) max_date,
row_number() over (partition by t.personID
order by t.date, t.starttime) rn
from table t) a
where a.rn = 1;
示例数据添加到小提琴:http://sqlfiddle.com/#!4/63c45/1
答案 1 :(得分:0)
这是您可以使用的查询,无需在查询中加入。您也可以将@ Dazzal的查询作为独立使用
SELECT ID, PERSONID, DATE, STARTTIME
(
SELECT ID, PERONID, DATE, STARTTIME, ROW_NUMBER() OVER(PARTITION BY personid ORDER BY STARTTIME, DATE) AS RN
FROM TABLE
) A
WHERE
RN = 1
答案 2 :(得分:0)
select a.id,a.accomp, a.accomp_name, a.start_year,a.end_year, a.company
from (select t.*,
min(t.start_year) over (partition by t.company) min_date,
max(t.end_year) over (partition by t.company) max_date,
row_number() over (partition by t.company
order by t.end_year desc) rn
from temp_123 t) a
where a.rn = 1;