我试图改进以下查询:
SELECT TID, INSERTDATE, TNAME, TSURNAME, TDATE1, TDATE2, TDATE3 FROM
(SELECT T1.TID,T2.INSERTDATE, T1.TNAME, T1.TSURNAME, T2.TDATE1, T2.TDATE2, T2.TDATE3, ROW_NUMBER() OVER (PARTITION BY T1.TID ORDER BY T2.INSERTDATE DESC) AS RN
FROM MEMBER T1 INNER JOIN MEMBERPROMOTION T2 ON T1.TID=T2.TID WHERE SOME CLAUSES AND
(TDATE1 >= TO_TIMESTAMP('15/07/2014', 'DD/MM/YYYY HH24:MI:SS') AND TDATE1 <= TO_TIMESTAMP('14/08/2014', 'DD/MM/YYYY HH24:MI:SS')) OR
(TDATE2 >= TO_TIMESTAMP('15/07/2014', 'DD/MM/YYYY HH24:MI:SS') AND TDATE2 <= TO_TIMESTAMP('14/08/2014', 'DD/MM/YYYY HH24:MI:SS')) OR
(TDATE3 >= TO_TIMESTAMP('15/07/2014', 'DD/MM/YYYY HH24:MI:SS') AND TDATE3 <= TO_TIMESTAMP('14/08/2014', 'DD/MM/YYYY HH24:MI:SS')))
ORDERED WHERE RN = 1;
MEMBER
TID TNAME TSURNAME
-------------------------------
1 BLA BLABLA
2 BL BLBL
MEMBERPROMOTIONS
MPID TID INSERTDATE TDATE1 TDATE2 TDATE3
--------------------------------------------------------
1 1 11/06/2012 19/07/2013 19/07/2013 19/07/2013
2 1 05/08/2013 19/07/2014 19/07/2014 19/07/2014
3 2 05/08/2013 02/08/2014 21/07/2014 02/08/2014
预期结果
TID INSERTDATE TDATE1 TDATE2 TDATE3
--------------------------------------------------------
1 05/08/2013 19/07/2014 19/07/2014 19/07/2014
2 05/08/2013 02/08/2014 21/07/2014 02/08/2014
2 05/08/2013 02/08/2014 21/07/2014 02/08/2014
MEMBER表有成员信息,它与TID列上的MEMBERPROMOTIONS表有关系。
如你所见;我有日期输入,我在输入日期之间选择至少一个日期(date1,date2,date3)。我只想要max(INSERTDATE)行,所以我使用了OVER()。
这是我想要完成的事情:
如果TDATE1,TDATE2和TDATE3相同,我想要单行返回,否则我期望多行。关键是我想根据TDATE1,TDATE2和TDATE3进行分组。
答案 0 :(得分:0)
我认为你正在寻找一个将三个TDATEx
列转换成行的插件;然后将每个与你的日期范围进行比较。您已将此标记为10g,因此11g unpivot运算符不可用,因此需要以旧方式完成:
SELECT MP.MPID, MP.TID, MP.INSERTDATE, T.RN AS TDATE_NUM,
CASE T.RN
WHEN 1 THEN MP.TDATE1
WHEN 2 THEN MP.TDATE2
WHEN 3 THEN MP.TDATE3
END AS TDATE
FROM (SELECT LEVEL AS RN FROM DUAL CONNECT BY LEVEL <= 3) T
CROSS JOIN MEMBERPROMOTION MP
ORDER BY MP.MPID, RN;
这给了你:
MPID TID INSERTDATE TDATE_NUM TDATE
---------- ---------- ---------- ---------- ----------
1 1 11/06/2012 1 19/07/2013
1 1 11/06/2012 2 19/07/2013
1 1 11/06/2012 3 19/07/2013
2 1 05/08/2013 1 19/07/2014
2 1 05/08/2013 2 19/07/2014
2 1 05/08/2013 3 19/07/2014
3 2 05/08/2013 1 02/08/2014
3 2 05/08/2013 2 21/07/2014
3 2 05/08/2013 3 02/08/2014
使用它而不是原始表:
SELECT TID, MAX(INSERTDATE), TNAME, TSURNAME, TDATE
FROM (
SELECT M.TID, MP.INSERTDATE, M.TNAME, M.TSURNAME, MP.TDATE_NUM, MP.TDATE
FROM MEMBER M
INNER JOIN (
SELECT MP.MPID, MP.TID, MP.INSERTDATE, T.RN AS TDATE_NUM,
CASE T.RN
WHEN 1 THEN MP.TDATE1
WHEN 2 THEN MP.TDATE2
WHEN 3 THEN MP.TDATE3
END AS TDATE
FROM (SELECT LEVEL AS RN FROM DUAL CONNECT BY LEVEL <= 3) T
CROSS JOIN MEMBERPROMOTION MP
) MP
ON MP.TID=M.TID
WHERE -- SOME CLAUSES AND
MP.TDATE >= TO_TIMESTAMP('15/07/2014', 'DD/MM/YYYY HH24:MI:SS')
AND MP.TDATE <= TO_TIMESTAMP('14/08/2014', 'DD/MM/YYYY HH24:MI:SS')
)
GROUP BY TID, TNAME, TSURNAME, TDATE;
给出:
TID INSERTDATE TNAME TSURNAME TDATE_NUM TDATE
---------- ---------- ---------- ---------- ---------- ----------
1 05/08/2013 BLA BLABLA 1 19/07/2014
1 05/08/2013 BLA BLABLA 2 19/07/2014
1 05/08/2013 BLA BLABLA 3 19/07/2014
2 05/08/2013 BL BLBL 1 02/08/2014
2 05/08/2013 BL BLBL 2 21/07/2014
2 05/08/2013 BL BLBL 3 02/08/2014
然后那可能是你内心的疑问;并且您可以将分组应用于该结果集:
SELECT TID, MAX(INSERTDATE) AS INSERTDATE, TNAME, TSURNAME, TDATE
FROM (
SELECT M.TID, MP.INSERTDATE, M.TNAME, M.TSURNAME, MP.TDATE_NUM, MP.TDATE
FROM MEMBER M
INNER JOIN (
SELECT MP.MPID, MP.TID, MP.INSERTDATE, T.RN AS TDATE_NUM,
CASE T.RN
WHEN 1 THEN MP.TDATE1
WHEN 2 THEN MP.TDATE2
WHEN 3 THEN MP.TDATE3
END AS TDATE
FROM (SELECT LEVEL AS RN FROM DUAL CONNECT BY LEVEL <= 3) T
CROSS JOIN MEMBERPROMOTION MP
) MP
ON MP.TID=M.TID
WHERE -- SOME CLAUSES AND
MP.TDATE >= TO_TIMESTAMP('15/07/2014', 'DD/MM/YYYY HH24:MI:SS')
AND MP.TDATE <= TO_TIMESTAMP('14/08/2014', 'DD/MM/YYYY HH24:MI:SS')
)
GROUP BY TID, TNAME, TSURNAME, TDATE
ORDER BY TID, INSERTDATE, TDATE;
,并提供:
TID INSERTDATE TNAME TSURNAME TDATE
---------- ---------- ---------- ---------- ----------
1 05/08/2013 BLA BLABLA 19/07/2014
2 05/08/2013 BL BLBL 21/07/2014
2 05/08/2013 BL BLBL 02/08/2014