0

我有以下日期表:

dateID INT (PK),
personID INT (FK),
date DATE,
starttime VARCHAR, --Always in a format of 'HH:MM'

我想要做的是我想为每个人提取具有最低日期(主要条件)和开始时间(次要条件)的行(所有列,包括 PK)。例如,如果我们有

第 1 行(日期 = '2013-04-01' 和开始时间 = '14:00')

row2(日期 = '2013-04-02' 和开始时间 = '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 倍。

4

3 回答 3

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

于 2013-04-03T15:14:41.237 回答
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
于 2013-04-04T11:25:09.117 回答
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;
于 2013-08-27T07:39:24.153 回答