我基本上有与问题中指定的问题相同的问题:
Pairing Send and Receive Data Rows in SQL
但是我没有可以使事情变得唯一的用户/批处理组合,因此基本上具有这样的东西:
KEY MODULE EVENTDTTM ACTION
-------------------------------------
1 A 01/01 SENT
2 A 02/01 RECEIVE
4 A 03/01 SENT
3 A 04/01 RECEIVE
5 A 05/01 SENT
6 A 06/01 SENT
7 A 07/01 RECEIVE
8 A 08/01 SENT
由于缺少事件,因此它们的累加不好,并且排序依赖于DTTM,而不是键顺序,但是我需要为每条记录建立一些配对,最后是这样的东西:
MODULE CUR_KEY NEXT_KEY PREV_KEY
-----------------------------------------------
A 1 2 NULL
A 2 NULL 1
A 3 NULL 4
A 4 3 NULL
A 5 (NULL/7) NULL
A 6 7 NULL
A 7 NULL 6
A 8 NULL NULL
基本上匹配发送-接收对,以便它们根据时间戳与最接近的一对链接。只要其余顺序正确,是5指向7还是NULL并不重要。 (8)还没有任何匹配项,并且还存在相反的内容(接收未发送)。
这略高于我的认知水平,因此对您有所帮助:) 我应该加入作为cur和subquery的合适下一个对象,然后与相反的对象或...合并吗?
答案 0 :(得分:1)
这是代码(使用自我联接):
select a.key as cur_key, a.module, b.key as next_key c.key as prev_key
from tab a full join tab b on a.key=b.key+1 full join tab c on and c.key = a.key-1
where a.action like 'S%'
and b.action like 'R%'
and c.action like 'S%'
and a.action like 'R%'
group by a.key
编辑: 这应该适用于“ greather”
select a.key as cur_key, a.module, b.key as next_key c.key as prev_key
from tab a
where a.key= (select key
from table t
where T.id > a.id
-- and (eventual binding condition)
and t.action like 'S%'
and a.action like 'R%'
order by t.id
FETCH FIRST ROW ONLY --equivalent to select top 1
) b
and c.key=(select key
from table T
where T.id < a.id
-- and (eventual binding condition)
and a.action like 'S%'
and t.action like 'R%'
order by t.id desc
FETCH FIRST ROW ONLY --equivalent to select top 1 (that was my original idea)
) c
group by a.key
答案 1 :(得分:1)
您可以使用 <?php
/**
* Returns the amount of weeks into the month a date is
* @param $date a YYYY-MM-DD formatted date
* @param $rollover The day on which the week rolls over
*/
function getWeeks($date, $rollover)
{
$cut = substr($date, 0, 8);
$daylen = 86400;
$timestamp = strtotime($date);
$first = strtotime($cut . "00");
$elapsed = ($timestamp - $first) / $daylen;
$weeks = 1;
for ($i = 1; $i <= $elapsed; $i++)
{
$dayfind = $cut . (strlen($i) < 2 ? '0' . $i : $i);
$daytimestamp = strtotime($dayfind);
$day = strtolower(date("l", $daytimestamp));
if($day == strtolower($rollover)) $weeks ++;
}
return $weeks;
}
//
echo getWeeks("2011-06-11", "sunday"); //outputs 2, for the second week of the month
?>
和LAG
函数。
Oracle 11g R2架构设置:
LEAD
查询1 :
CREATE TABLE Table1
("KEY" int, "MODULE" varchar2(1), "EVENTDTTM" timestamp, "ACTION" varchar2(7))
;
INSERT ALL
INTO Table1 ("KEY", "MODULE", "EVENTDTTM", "ACTION")
VALUES (1, 'A', '01-Jan-2018 12:00:00 AM', 'SENT')
INTO Table1 ("KEY", "MODULE", "EVENTDTTM", "ACTION")
VALUES (2, 'A', '01-Feb-2018 12:00:00 AM', 'RECEIVE')
INTO Table1 ("KEY", "MODULE", "EVENTDTTM", "ACTION")
VALUES (4, 'A', '01-Mar-2018 12:00:00 AM', 'SENT')
INTO Table1 ("KEY", "MODULE", "EVENTDTTM", "ACTION")
VALUES (3, 'A', '01-Apr-2018 12:00:00 AM', 'RECEIVE')
INTO Table1 ("KEY", "MODULE", "EVENTDTTM", "ACTION")
VALUES (5, 'A', '01-May-2018 12:00:00 AM', 'SENT')
INTO Table1 ("KEY", "MODULE", "EVENTDTTM", "ACTION")
VALUES (6, 'A', '01-Jun-2018 12:00:00 AM', 'SENT')
INTO Table1 ("KEY", "MODULE", "EVENTDTTM", "ACTION")
VALUES (7, 'A', '01-Jul-2018 12:00:00 AM', 'RECEIVE')
INTO Table1 ("KEY", "MODULE", "EVENTDTTM", "ACTION")
VALUES (8, 'A', '01-Aug-2018 12:00:00 AM', 'SENT')
SELECT * FROM dual
;
Results :
SELECT KEY ,
module ,
action ,
CASE
WHEN LEAD(action) OVER ( PARTITION BY module ORDER BY eventdttm ) = 'RECEIVE'
AND action = 'SENT' THEN LEAD(KEY) OVER ( PARTITION BY module ORDER BY eventdttm )
END AS NEXT_KEY ,
CASE
WHEN LAG(action) OVER ( PARTITION BY module ORDER BY eventdttm ) = 'SENT'
AND action = 'RECEIVE' THEN LAG(KEY) OVER ( PARTITION BY module ORDER BY eventdttm )
END AS PREV_KEY
FROM table1
ORDER BY KEY