[英]combining rows in same table sql
样本数据
id_type,seq_no,acct_name,_acct#,address
12345,67,jiimm,,167 s.40th st
12345,67,jiimm joe the 3rd,,167 s.40th st
12345,67,jiimm
12345,67,,0981_1,po box 1234
12345,80,Lee,,1234 street ave
12345,80,Lee
12345,80,,588_1,109 road st
码
SELECT `ID`_type,
seq_no,
MAX(`acct_name`) AS acct_name,
MAX(`acct_#`) AS acct_#,
address
FROM `test_table`
GROUP BY `ID`_type,
seq_no;
我想基于id_type和seq_no合并行。 我正在使用max合并行,但是由于MAX acct#,我正在覆盖所有现有地址和acct_names。
我的结果
id_type,seq_no.,acct_name,_acct#,address
12345,67,jiimm joe the 3rd,0981_1,167 s.40th st
12345,80,Lee,588_1,109 road st
理想的结果
12345,80,Lee,588_1,109 road st
12345,80,Lee,588_1,1234 street ave
12345,67,jiimm,0981_1,167 s.40th st
12345,67,jiimm,0981_1,po box 1234
12345,67,jiimm joe the 3rd,0981_1,167 s.40th st
这可以为您提供所需的信息,但请在上面的问题下方阅读我的评论/问题。 有一个模棱两可的“多选一排”的情况需要澄清。 在这种模棱两可的情况下,您暗示规则要求提供最小的非空白帐户名,此代码可以做到这一点,但是您可以看到它如何要求以一种方式处理帐户名,并以acct(#)处理并解决其他问题。方式。 我认为您正朝着基于难以记住的规则提供结果的应用程序前进。 这样的时髦规则最终都会被报告为缺陷,即使您发布了上述处理规则。 因此,您可能需要增强上游捕获该数据的过程,以提供更严格的数据。
SQLFIDDLE链接 -简而言之,内部查询填充缺少的值,然后外部结果集提供不同的行。 我用不为空的空白值进行了测试。 我确实努力地添加了代码来处理空值,但是我没有使用空值对其进行测试,因此,如果可以使用生产环境,则建议对它进行测试。
select distinct * from (
select d.id_type, d.seq_no
,coalesce( nullif( acct_name, ''), min_acct_name ) as merged_acct_name
,coalesce( nullif( acct, ''), max_acct ) as merged_acct
,coalesce( nullif( address, ''), max_address ) as merged_address
from test_table d
left join ( select id_type, seq_no
,max( acct ) as max_acct
,max( address ) as max_address
from test_table
group by id_type, seq_no
) as max_
on max_.id_type = d.id_type and max_.seq_no = d.seq_no
and ( coalesce( d.acct,'' ) = ''
or coalesce( d.address,'' ) = '' )
left join ( select id_type, seq_no
,min( acct_name ) as min_acct_name
from test_table
where coalesce( acct_name, '' ) <> ''
group by id_type, seq_no
) as min_
on min_.id_type = d.id_type and min_.seq_no = d.seq_no
and coalesce( d.acct_name,'' ) = ''
) as t
order by id_type, seq_no desc, merged_acct_name, merged_acct, merged_address
尝试这个:
select distinct t1.id_type, t1.seq_no
,coalesce( t1.acct_name, t2.acct_name ) as merged_acct_name
,coalesce( t1.acct, t2.acct ) as merged_acct
,coalesce( t1.address, t2.address ) as merged_address
from test_table t1
left join test_table t2
on t1.id_type = t2.id_type
and t1.seq_no = t2.seq_no
where concat(coalesce( t1.acct_name, t2.acct_name )
,coalesce( t1.acct, t2.acct )
,coalesce( t1.address, t2.address ) ) is not null
order by t1.id_type, t1.seq_no;
要么:
select distinct t1.id_type, t1.seq_no
,coalesce( t1.acct_name, t2.acct_name ) as merged_acct_name
,coalesce( t1.acct, t3.acct ) as merged_acct
,coalesce( t1.address, t4.address ) as merged_address
from test_table t1
left join test_table t2
on t1.id_type = t2.id_type
and t1.seq_no = t2.seq_no
left join test_table t3
on t1.id_type = t3.id_type
and t1.seq_no = t3.seq_no
left join test_table t4
on t1.id_type = t4.id_type
and t1.seq_no = t4.seq_no
where concat(coalesce( t1.acct_name, t2.acct_name )
,coalesce( t1.acct, t3.acct )
,coalesce( t1.address, t4.address ) ) is not null
order by t1.id_type, t1.seq_no;
SELECT
D1.id_type
, D1.seq_no
, IFNULL(D1.acct_name, (SELECT MIN(acct_name) FROM data D WHERE D.id_type = D1.id_type AND D.seq_no = D1.seq_no)) t
, IFNULL(D1.acct_no, (SELECT MAX(acct_no) FROM data D WHERE D.id_type = D1.id_type AND D.seq_no = D1.seq_no)) s
, D1.address
FROM data D1
WHERE D1.address IS NOT NULL
ORDER BY id_type, seq_no DESC, acct_name
;
回报
| ID_TYPE | SEQ_NO | T | S | ADDRESS |
|---------|--------|-------------------|--------|-----------------|
| 12345 | 80 | Lee | 588_1 | 109 road st |
| 12345 | 80 | Lee | 588_1 | 1234 street ave |
| 12345 | 67 | jiimm | 0981_1 | po box 1234 |
| 12345 | 67 | jiimm | 0981_1 | 167 s.40th st |
| 12345 | 67 | jiimm joe the 3rd | 0981_1 | 167 s.40th st |
除第三行和第四行的顺序外,这与您的预期输出一致。 但是,对于大量数据, MAX
和MIN
将越来越有限。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.