Oracle SQL max()具有group by - 重复值

时间:2017-06-03 00:41:59

标签: sql oracle

这是我创建的查询的简化版本,它提供了我想要的内容(所有带有所选cpnt_id的stud_id的列表,compl_dte中是否有值,但仅当项目的UserInput仅限于只有1条记录。

map.fitBounds(arrayStreetExtent)

当UserInput指定2个或更多Item时运行它,它返回正确的行,但是对于每个stud_id值,compl_dte的返回值总是相同的(因为使用了max(compl_dte)我确定) 。我只是不确定我需要做些什么来确保返回的compl_dte是stud_id / cpnt_id对的最大值,而不是c_cn_id的stud_id的最大值。

表值:

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是stud_id = *和cpnt_id = a:

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和b:

stud_id cpnt_id compl_dte
1    a    5/5/2017
2    a
3    a
4    a

这不是我想要的。结果我正在寻找那种情况:

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

首先发布在这里,希望一切都有意义,我已经在正确的地方提出过要求了!

2 个答案:

答案 0 :(得分:0)

我认为问题可能是STUDLRNHIST内嵌视图之间缺少连接谓词。
在您提供的查询中,STUD内联视图是STUDENTITEM之间的笛卡尔积,然后外部连接到LRNHIST视图,该视图确实有一个CMPL_DTE 1 {}每STUD_ID / CPNT_ID对。但由于OUTER JOIN仅在STUD_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加入,那么May 5th STUD 1 - a LRNHST 1 - a的{​​{1}}行将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

因为这只会加入OctMaySTUD条记录都可以免费与1-a的{​​{1}}匹配LRNHST匹配其1群体和1-a群体1-bCPNT_ID

现在,如果您同时加入LRNHST,则只会返回与两者 CPNT_IDSTUD_ID匹配的May条记录。 (1-aOct1-bSELECT 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为空,其中RDD条记录不匹配。

答案 1 :(得分:0)

使用因子子查询。

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;