[英]Oracle SQL max() with group by - duplicated values
这是我创建的查询的简化版本,它提供了我想要的信息(具有选定cpnt_id的所有stud_id的列表,compl_dte中是否有值,但仅当Item的UserInput仅限于1条记录时。
select stud.*, lrnhist.* from
(select s.stud_id,
i.cpnt_id
from student s, item i
where s.stud_id in [UserInput]
c.cpnt_id in [UserInput]
) stud
left outer join
(select lh.stud_id,
lh.cpnt_id,
max(lh.compl_dte) compl_dte
from learnhist lh
where lh.cpnt_id in [UserInput]
group by lh.stud_id, lh.cpnt_id
)
on stud.stud_id = lrnhist.stud_id
在UserInput指定2个或更多项目的情况下运行该命令时,它将返回正确的行,但对于stud_id的每个值,compl_dte的返回值始终是相同的(因为我确定使用max(compl_dte))。 我只是不确定我需要做什么以确保返回的compl_dte是stud_id / cpnt_id对的最大值,而不是stud_id的最大值,与cpnt_id无关。
表值:
student
stud_id
1
2
3
4
item
cpnt_id
a
b
c
d
learnhist
stud_id cpnt_id compl_dte
1 a 5/5/2017
1 a 3/3/2016
1 b 10/10/2016
2 c 8/8/2016
3 b 2/2/2017
UserInput为stud_id = *和cpnt_id = a的结果:
stud_id cpnt_id compl_dte
1 a 5/5/2017
2 a
3 a
4 a
哪个是对的。 UserInput为stud_id = *和cpnt_id = a和b的结果:
stud_id cpnt_id compl_dte
1 a 5/5/2017
1 b 5/5/2017
2 a
2 b
3 a 2/2/2017
3 b 2/2/2017
4 a
4 b
这不是我想要的。 在这种情况下,我正在寻找结果:
stud_id cpnt_id compl_dte
1 a 5/5/2017
1 b 10/10/2016
2 a
2 b
3 a
3 b 2/2/2017
4 a
4 b
希望在这里第一篇文章都有意义,我已经在正确的位置提出要求!
我认为问题可能是STUD
和LRNHIST
内联视图之间缺少LRNHIST
谓词。
在您提供的查询中, STUD
内联视图是STUDENT
和ITEM
之间的笛卡尔乘积,然后将其外部连接到LRNHIST
视图,该视图确实每个STUD_ID
/ CPNT_ID
对具有一个CMPL_DTE
。 但是由于OUTER JOIN
仅基于STUD_ID
谓词, STUD_ID
您还将在STUD.CPNT_ID <> LRNHST.CPNT_ID
获得匹配STUD.CPNT_ID <> LRNHST.CPNT_ID
,从而提供额外的行。
您将其分解并分别查看内联视图:
对于STUD
查询:
SELECT STUDENT.STUD_ID, ITEM.CPNT_ID FROM STUDENT
CROSS JOIN ITEM
WHERE STUDENT.STUD_ID IN (1,2,3,4)
AND ITEM.CPNT_ID IN ('a','b','c','d');
结果:
stud_id cpnt_id
1 a
1 b
1 c
1 d
2 a
2 b
2 c
2 d
... etc
因此,我们可以在最终查询中期待所有这些行。
如果您单独查看LRNHST
:
SELECT LEARNHIST.STUD_ID,
LEARNHIST.CPNT_ID,
MAX(LEARNHIST.COMPL_DTE) COMPL_DTE
FROM LEARNHIST
GROUP BY LEARNHIST.STUD_ID, LEARNHIST.CPNT_ID;
实际上,每个stud_id-cpnt_id对仅存在一行(在learnhist
中存在):
stud_id cpnt_id compl_dte
1 b October, 10 2016 00:00:00
1 a May, 05 2017 00:00:00
3 b February, 02 2017 00:00:00
2 c August, 08 2016 00:00:00
现在,如果仅使用STUD_ID
加入, STUD_ID
获得May 5th
一行,其中STUD
具有1 - a
而LRNHST
具有1 - a
,但是您还将获得其中LRNHST
具有1 -b
的行,因为没有连接基于CPNT_ID
谓词。 如果选择全部五列,则可以看到重复项的位置:
SELECT STUD.*, LRNHIST.* FROM (
SELECT STUDENT.STUD_ID, ITEM.CPNT_ID FROM STUDENT
CROSS JOIN ITEM
WHERE STUDENT.STUD_ID IN (1,2,3,4)
AND ITEM.CPNT_ID IN ('a','b','c','d')) STUD
LEFT OUTER JOIN (SELECT LEARNHIST.STUD_ID,
LEARNHIST.CPNT_ID,
MAX(LEARNHIST.COMPL_DTE) COMPL_DTE
FROM LEARNHIST
GROUP BY LEARNHIST.STUD_ID, LEARNHIST.CPNT_ID
) LRNHIST
ON STUD.STUD_ID = LRNHIST.STUD_ID
ORDER BY 1 ASC, 2 ASC, 3 ASC, 4 ASC, 5 ASC;
结果:
s_stud s_cpnt l_stud l_cpnt l_compl
1 a 1 a May, 05 2017 00:00:00
1 a 1 b October, 10 2016 00:00:00
1 b 1 a May, 05 2017 00:00:00
1 b 1 b October, 10 2016 00:00:00
1 c 1 a May, 05 2017 00:00:00
1 c 1 b October, 10 2016 00:00:00
1 d 1 a May, 05 2017 00:00:00
1 d 1 b October, 10 2016 00:00:00
2 a 2 c August, 08 2016 00:00:00
... etc
因为这只是在加入stud_id
,无论是Oct
和May
的记录可以随意搭配STUD
的1-a
匹配LRNHST
的1
在它的两个1-a
对地表和1-b
组。
现在,如果你加入CPNT_ID
为好,只有LRNHST
符合两者的记录CPNT_ID
和STUD_ID
将被退回。 (对于1-a
May
Oct
对于1-b
1-a
Oct
)
SELECT STUD.STUD_ID, STUD.CPNT_ID, LRNHIST.COMPL_DTE FROM (
SELECT STUDENT.STUD_ID, ITEM.CPNT_ID FROM STUDENT
CROSS JOIN ITEM
WHERE STUDENT.STUD_ID IN (1,2,3,4)
AND ITEM.CPNT_ID IN ('a','b','c','d')) STUD
LEFT OUTER JOIN (SELECT LEARNHIST.STUD_ID,
LEARNHIST.CPNT_ID,
MAX(LEARNHIST.COMPL_DTE) COMPL_DTE
FROM LEARNHIST
GROUP BY LEARNHIST.STUD_ID, LEARNHIST.CPNT_ID
) LRNHIST
ON STUD.STUD_ID = LRNHIST.STUD_ID
AND STUD.CPNT_ID = LRNHIST.CPNT_ID
ORDER BY 1 ASC, 2 ASC;
结果:
stud_id cpnt_id compl_dte
1 a May, 05 2017 00:00:00
1 b October, 10 2016 00:00:00
1 c (null)
1 d (null)
2 a (null)
2 b (null)
2 c August, 08 2016 00:00:00
2 d (null)
... etc
现在你应该有每次只有一排STUD_ID
CPNT_ID
对,用空的compl_dte
没有地方LRNHST
记录匹配。
使用分解的子查询。
WITH all_ids AS (
SELECT s.stud_id as stud_id,
i.cpnt_id as cpnt_id
FROM student s
CROSS JOIN item i )
SELECT stud_id, cpnt_id, max(lh.compl_dte) as compl_dte
FROM all_ids
LEFT JOIN learnhist lh USING (stud_id, cpnt_id)
WHERE cpnt_id IN ('a', 'b')
GROUP BY stud_id, cpnt_id
ORDER BY stud_id;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.