SQL在Oracle中合并行
我想合并一些行 首先,我的表格和数据如下所示SQL在Oracle中合并行,sql,oracle,merge,rows,Sql,Oracle,Merge,Rows,我想合并一些行 首先,我的表格和数据如下所示 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 Michae
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
现在我知道为什么我的查询结果是错误的,不是我想要的,但我仍然找不到方法
事实上,有严格的规则来区分哪些是重复的母亲、父亲、工作,哪些不是朋友
由于某些原因,我无法修改表的结构。
我已经将这个问题的内容从我的商业术语中改了过来,并简化了情况来解释
请给出任何建议以重试假设“母亲”、“父亲”和“工作”是唯一的类型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分析函数在所有行的单独列中输出父、母和作业类型\u cd的类型\u id
然后,只需过滤行以仅显示type_cd='FRIEND'行。自连接表即可:
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”,当然,如果您使用一个过滤器,例如:WHERE t1.type_cd='FATHER'来给出另一种方法,那么它可以被丢弃
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'
您是否尝试使用“朋友栏上的max”将其从组中删除?@JorgeCampos是的,我尝试过,但行数应为三,因为有三个朋友。然后,您的解决方案将是实际查询的内部联接,以及一个子查询,如select。。。。。。其中键入\u CD='FRIEND'此连接将为您提供3个结果。。。试试看。哦,不需要在你的查询中使用“1=1”,我知道这可能来自一个应用程序,在这个应用程序中,一个懒惰的程序员不想检查前面的每个条件=D@JorgeCampos谢谢,我正在尝试你的建议。