我想合并一些行。
首先,我的表和数据如下所示
GRP CRRO_NO TYPE_CD TYPE_ID
PERSON 1111 FATHER Tom
PERSON 1111 MOTHER Jennifer
PERSON 1111 JOB_ Teacher
PERSON 1111 FRIEND Jimmy
PERSON 1111 FRIEND Kim
PERSON 1111 FRIEND Michael
我希望得到像
这样的结果GRP CRRO_NO FATHER MOTHER JOB_ FRIEND
PERSON 1111 Tom Jennifer Teacher Jimmy
PERSON 1111 Tom Jennifer Teacher Kim
PERSON 1111 Tom Jennifer Teacher Michael
有了这种情况,如何编写SQL?
我一直在尝试
SELECT T1.GRP_CD GRP, T1.CRRO_NO CRRO
, MAX(T1.MOTHER) MOTHER, MAX(T1.FATHER) FATHER, MAX(T1.JOB_) JOB, T1.FRIEND FRIEND
FROM (
SELECT DISTINCT
GRP_CD
,CRRO_NO
,CASE WHEN TYPE_CD = 'FATHER' THEN TYPE_ID ELSE '' END FATHER
,CASE WHEN TYPE_CD = 'MOTHER' THEN TYPE_ID ELSE '' END MOTHER
,CASE WHEN TYPE_CD = 'JOB_' THEN TYPE_ID ELSE '' END JOB_
,CASE WHEN TYPE_CD = 'FRIEND' THEN TYPE_ID ELSE '' END FRIEND
FROM TMP
WHERE 1=1 AND TRIM(CRRO_NO) = '1111'
) T1
WHERE T1.CRRO_NO = '1111'
GROUP BY T1.GRP_CD, T1.CRRO_NO, T1.FRIEND
;
然后,上面的sql结果是
GRP CRRO_NO MOTHER FATHER JOB FRIEND
PERSON 1111 Jennifer Tom Teacher (null)
PERSON 1111 (null) (null) (null) Jimmy
PERSON 1111 (null) (null) (null) Kim
PERSON 1111 (null) (null) (null) Michael
现在我知道为什么我的查询结果是错误的(不是我想要的),但我仍然无法找到方法。
实际上,有严格的规则来分类哪一个会被重复(母亲,父亲,工作),哪些不会(朋友)
由于某些原因,我无法修改表格的结构。 (我已根据业务条款更改了此问题的内容,并简化了解释的情况)
请提出任何建议再试一次
答案 0 :(得分:1)
假设'母亲','父亲'和' JOB _'是唯一的type_cd值,你可以实现你的目标:
WITH sample_data AS (SELECT 'PERSON' grp, 1111 crro_no, 'FATHER' type_cd, 'Tom' type_id FROM dual UNION ALL
SELECT 'PERSON' grp, 1111 crro_no, 'MOTHER' type_cd, 'Jennifer' type_id FROM dual UNION ALL
SELECT 'PERSON' grp, 1111 crro_no, 'JOB_' type_cd, 'Teacher' type_id FROM dual UNION ALL
SELECT 'PERSON' grp, 1111 crro_no, 'FRIEND' type_cd, 'Jimmy' type_id FROM dual UNION ALL
SELECT 'PERSON' grp, 1111 crro_no, 'FRIEND' type_cd, 'Kim' type_id FROM dual UNION ALL
SELECT 'PERSON' grp, 1111 crro_no, 'FRIEND' type_cd, 'Michael' type_id FROM dual)
-- end of mimicking a table called "sample_data" with your data in it.
-- see the SQL below:
SELECT grp,
crro_no,
father,
mother,
job_,
type_id friend
FROM (SELECT grp,
crro_no,
type_cd,
type_id,
MAX(CASE WHEN type_cd = 'FATHER' THEN type_id END) OVER (PARTITION BY grp, crro_no) father,
MAX(CASE WHEN type_cd = 'MOTHER' THEN type_id END) OVER (PARTITION BY grp, crro_no) mother,
MAX(CASE WHEN type_cd = 'JOB_' THEN type_id END) OVER (PARTITION BY grp, crro_no) job_
FROM sample_data)
WHERE type_cd = 'FRIEND';
GRP CRRO_NO FATHER MOTHER JOB_ FRIEND
------ ---------- -------- -------- -------- --------
PERSON 1111 Tom Jennifer Teacher Michael
PERSON 1111 Tom Jennifer Teacher Jimmy
PERSON 1111 Tom Jennifer Teacher Kim
这可以通过使用MAX()分析函数在所有行的不同列中输出父,母和作业type_cd的type_id来实现。
然后,只需过滤行以显示type_cd =' FRIEND'行。
答案 1 :(得分:0)
自联接表可以解决问题:
select distinct t1.GRP, t1.CRRO_NO, t2.TYPE_ID as father, t3.TYPE_ID as mother, t4.TYPE_ID as JOB_, t5.TYPE_ID as FRIEND
from TMP t1
inner join TMP t2 on t2.CRRO_NO = t1.CRRO_NO
and t2.TYPE_CD = 'FATHER'
inner join TMP t3 on t3.CRRO_NO = t1.CRRO_NO
and t3.TYPE_CD = 'MOTHER'
inner join TMP t4 on t4.CRRO_NO = t1.CRRO_NO
and t4.TYPE_CD = 'JOB_'
inner join TMP t5 on t5.CRRO_NO = t1.CRRO_NO
and t5.TYPE_CD = 'FRIEND';
但请注意,由于您未指定过滤谓词(WHERE子句),因此表格TMP中的所有结果都将被处理,并且您将有重复的结果,因此使用了' distinct& #39;将是强制性的,当然如果您使用过滤器,例如:WHERE t1.type_cd = 'FATHER'
答案 2 :(得分:0)
只是提供另一种方法。
with MFJQuery as (
select * from (
select
A.GRP,
A.CRRO_NO,
A.TYPE_CD,
A.TYPE_ID
from test_data A
where A.TYPE_CD <> 'FRIEND')
pivot
(
max(TYPE_ID)
for TYPE_CD in ('MOTHER' as "MOTHER",
'FATHER' as "FATHER",
'JOB_' as "JOB")
))
select A.GRP, A.CRRO_NO, B.MOTHER, B.FATHER, B.JOB, A.TYPE_ID as FRIEND
from test_data A inner join
MFJQuery B on A.GRP = B.GRP
and A.CRRO_NO = B.CRRO_NO
where
A.TYPE_CD = 'FRIEND'