我需要一些有关复杂SQL查询的帮助。
这是我的设置:我有两个表USER_TABLE
和USER_VISIT_STAT
。
USER_TABLE
具有诸如ID,USER_NAME,UID,DEPARTMENT
和
USER_VISIT_STAT
的列类似ID,USERID,LAST_VISIT_DATE
。 USERID
表的USER_VISIT_STAT
字段保存USER_TABLE.ID
。
当用户登录到应用程序时,他的当前日期保存在USER_VISIT_STAT
表中(请参阅屏幕截图)。因此,我需要获取自最近两年以来未连接到应用程序的用户详细信息。但是我们必须注意UID
。 (意味着您可以在USER_TABLE
中看到两个条目,它们具有相同的UID
,但大小写不同。在USER_VISIT_STAT
中,您可以看到101 LAST_VISIT_DATE
是31-08-18和103 LAST_VISIT_DATE
是20-01-16
。因此,您必须忽略这两个ID,因为用户相同并且他处于活动状态)。在响应表中,我需要用户名,用户uid,用户部门和用户max(最后激活日期)。
+--------------------------------------+
| USER_TABLE |
+--------------------------------------+
| ID | NAME | UID | DEPARTMENT |
+--------------------------------------+
| 101 | PRAKASH | US45 | ENGG |
| 102 | RAJESH | US22 | ENGG |
| 103 | PRAKASH | us45 | HR |
| 104 | HARI | US9 | ENGG |
| 105 | MAYANK | US90 | HR |
+--------------------------------------+
+--------------------------------+
| USER_VISIT_STAT |
+--------------------------------+
| ID | USID | MAX(LAST_VISIT_DATE)|
+--------------------------------+
| 1 | 101 | 31-08-18 |
| 2 | 102 | 30-08-18 |
| 3 | 101 | 30-08-18 |
| 4 | 103 | 20-01-16 |
| 5 | 104 | 29-08-16 |
| 6 | 105 | 19-07-16 |
| 7 | 101 | 12-06-16 |
| 8 | 102 | 12-06-16 |
| 9 | 104 | 13-04-16 |
+--------------------------------+
+-------------------------------------------------+
| RESPONSE |
+-------------------------------------------------+
| NAME | UID | DEPARTMENT | LAST_VISIT_DATE |
+-------------------------------------------------+
| HARI | US9 | ENGG | 29-08-16 |
| MAYANK | US09 | HR | 19-07-16 |
+-------------------------------------------------+
答案 0 :(得分:2)
我将使用row_number
来获取每个uid
的最新用户详细信息,并将它们加入到uid
的最后访问日期中,并以此进行过滤:
SELECT name, u.uid, department, max_visit
FROM (SELECT name,
uid,
department,
ROW_NUMBER() OVER (PARTITION BY uid ORDER BY id DESC) AS rn
FROM user_table) u
JOIN (SELECT uid, MAX(last_visit_date) AS max_visit
FROM user_visit_stat
GROUP BY uid
HAVING MONTHS_BETWEEN(sysdate, MAX(last_visit_date)) >= 24) us ON u.uid = us.uid
WHERE rn = 1
答案 1 :(得分:0)
尝试以下方法:
select a.uid,a.name,b.department,a.id,lastvisit
from
(select uid,name,max(id) as id
from USER_TABLE group by uid,name)a
inner join USER_TABLE b on a.uid=b.uid
inner join
(select uid,max(LAST_VISIT_DATE) as lastvisit
group by uid having max(LAST_VISIT_DATE)< trunc(sysdate, 'yyyy') - interval '2' year)x
on a.id=x.id
答案 2 :(得分:0)
使用聚合函数并加入
select u.*,t.last_visit from
(
select min(ID) as ID ,Name, UPPER(UID) as UID,DEPARTMENT from USER_TABLE
group by Name, UPPER(UID),DEPARTMENT
) as u
join
(
select UID,max(LAST_VISIT_DATE) as last_visit from USER_VISIT_STAT us
group by UID
having max(LAST_VISIT_DATE) between add_months(sysdate,-26) and add_months(sysdate,-24)
) as t
on u.ID=t.UID
从对话看来,您似乎需要以下内容
select u.*, x.last_visit from
(
select Name, UPPER(UID) as UID,DEPARTMENT from USER_TABLE
group by Name, UPPER(UID),DEPARTMENT
) as u
join
(
select a.name,a.last_visit from
(
select distinct iu.NAME,last_visit from
(
select USID,max(LAST_VISIT_DATE) as last_visit from USER_VISIT_STAT us
group by USID
having max(LAST_VISIT_DATE) between add_months(sysdate,-26) and add_months(sysdate,-24)
) as t1
join
USER_TABLE as iu on t1.USID=iu.ID
) a left join
(
select distinct iu.NAME,
(
select USID from USER_VISIT_STAT us
group by USID
having min(LAST_VISIT_DATE) between add_months(sysdate,-23) and add_months(sysdate,0)
) as t1
join
USER_TABLE as iu on t1.UID=iu.ID
) b on a.NAME=b.NAME
where b.NAME is null
) x on u.Name=x.Name
答案 3 :(得分:0)
类似
select uid,name,department,last_visit_date
from (
select
a.id id, max(a.id) over (partition by a.uid) maxid,
a.uid uid,a.name name,a.department department,
max(last_visit_date) over (partition by a.uid) last_visit_date
from
user_table a, user_visit_stat b
where
a.id=b.uid
)
where last_visit_date<=add_years(sysdate,-2) and a.id=maxid
答案 4 :(得分:0)
使用MAX()函数的解析形式,将其划分为UID的大写字母即可解决此问题。 SQL Fiddle
可作为演示查询1 :
SELECT
M.LAST_VISIT_DATE, U.*
FROM (
SELECT
U."UID"
, V.LAST_VISIT_DATE
, MAX(V.LAST_VISIT_DATE) OVER(PARTITION BY UPPER(U."UID")) MAX_VISIT
FROM USER_TABLE U
INNER JOIN USER_VISIT_STAT V ON U.ID = V.USID
) M
INNER JOIN USER_TABLE U ON M."UID" = U."UID"
WHERE M.MAX_VISIT < ADD_MONTHS(SYSDATE,-24)
AND M.LAST_VISIT_DATE = M.MAX_VISIT
Results :
| LAST_VISIT_DATE | ID | NAME | UID | DEPARTMENT |
|-----------------------|-----|--------|------|------------|
| 2016-08-29 00:00:00.0 | 104 | HARI | US9 | ENGG |
| 2016-07-19 00:00:00.0 | 105 | MAYANK | US90 | HR |
Oracle 11g R2架构设置:
CREATE TABLE USER_TABLE
("ID" int, "NAME" varchar2(7), "UID" varchar2(4), "DEPARTMENT" varchar2(4))
;
INSERT ALL
INTO USER_TABLE ("ID", "NAME", "UID", "DEPARTMENT")
VALUES (101, 'PRAKASH', 'US45', 'ENGG')
INTO USER_TABLE ("ID", "NAME", "UID", "DEPARTMENT")
VALUES (102, 'RAJESH', 'US22', 'ENGG')
INTO USER_TABLE ("ID", "NAME", "UID", "DEPARTMENT")
VALUES (103, 'PRAKASH', 'us45', 'HR')
INTO USER_TABLE ("ID", "NAME", "UID", "DEPARTMENT")
VALUES (104, 'HARI', 'US9', 'ENGG')
INTO USER_TABLE ("ID", "NAME", "UID", "DEPARTMENT")
VALUES (105, 'MAYANK', 'US90', 'HR')
SELECT * FROM dual
;
CREATE TABLE USER_VISIT_STAT
("ID" int, "USID" int, "LAST_VISIT_DATE" timestamp)
;
INSERT ALL
INTO USER_VISIT_STAT ("ID", "USID", "LAST_VISIT_DATE")
VALUES (1, 101, '31-Aug-2018 12:00:00 AM')
INTO USER_VISIT_STAT ("ID", "USID", "LAST_VISIT_DATE")
VALUES (2, 102, '30-Aug-2018 12:00:00 AM')
INTO USER_VISIT_STAT ("ID", "USID", "LAST_VISIT_DATE")
VALUES (3, 101, '30-Aug-2018 12:00:00 AM')
INTO USER_VISIT_STAT ("ID", "USID", "LAST_VISIT_DATE")
VALUES (4, 103, '20-Feb-2016 12:00:00 AM')
INTO USER_VISIT_STAT ("ID", "USID", "LAST_VISIT_DATE")
VALUES (5, 104, '29-Aug-2016 12:00:00 AM')
INTO USER_VISIT_STAT ("ID", "USID", "LAST_VISIT_DATE")
VALUES (6, 105, '19-Jul-2016 12:00:00 AM')
INTO USER_VISIT_STAT ("ID", "USID", "LAST_VISIT_DATE")
VALUES (7, 101, '12-Jun-2016 12:00:00 AM')
INTO USER_VISIT_STAT ("ID", "USID", "LAST_VISIT_DATE")
VALUES (8, 102, '12-Jun-2016 12:00:00 AM')
INTO USER_VISIT_STAT ("ID", "USID", "LAST_VISIT_DATE")
VALUES (9, 104, '13-Apr-2016 12:00:00 AM')
SELECT * FROM dual
;