左外连接中的左侧是否有可能只重复一次

Is it possible that left side in a left outer join to repeat only once

我有一个场景。不确定是否可以通过简单的 sql 查询来实现。

表 1

create table table1 (rowno int,
                     fileid int,
                     filename varchar(50),
                     filedata varchar(50),
                     valid boolean
                     );

insert into table1 (RowNo , FileId , FileName , fileData , Valid) values
(1, 1, 'FileA', 'blah blah..', true),
(2, 1, 'FileA', 'blah blah..', true),
(3, 1, 'FileA', 'blah blah..', true),
(4, 1, 'FileA', 'blah blah..', true),
(1, 2, 'FileB', 'blah blah..', false),
(2, 2, 'FileB', 'blah blah..', true),
(3, 2, 'FileB', 'blah blah..', false);

上面会给出一个table如下,-

RowNo | FileId | FileName | Data        | Valid
1     |1       | FileA    | blah blah.. | TRUE 
2     |1       | FileA    | blah blah.. | TRUE 
3     |1       | FileA    | blah blah.. | TRUE 
4     |1       | FileA    | blah blah.. | TRUE 
1     |2       | FileB    | blah blah.. | FALSE 
2     |2       | FileB    | blah blah.. | TRUE 
3     |2       | FileB    | blah blah.. | FALSE 

表2

create table table2 (fileid int,
                     rowno int,
                     errormsg varchar(100)
                    );
insert into table2 (fileid , rowno , errormsg ) values (2,1,'manatory field is blank');
insert into table2 (fileid , rowno , errormsg ) values (2,3,'date format is wrong');

上面会给出一个table如下,-

FILEID  |ROWNO   |ERRORMSG   
2       |1       |manatory field is blank 
2       |3       |date format is wrong 

如果我用下面的查询加入上面的 table,-

select distinct t1.FILENAME,tot.TOTALREC, VALIDREC,coalesce((tot.TOTALREC- VALIDREC),0)INVALIDREC, t2.Rowno , case when coalesce((tot.TOTALREC- VALIDREC),0)=0 then null else t1.filedata end as ErrorData , t2.errormsg as ErrorMessage
from table1 t1
join (select count(*) totalrec, fileid from table1 group by fileid)tot on t1.fileid=tot.fileid
join (select count(*) VALIDREC , fileid from table1 where valid=true group by fileid)valid on t1.fileid=valid.fileid
left outer join table2 t2 on t1.fileid=t2.fileid 
order by t1.FILENAME;

我得到以下结果,-

实际结果

FILENAME | TOTALREC | VALIDREC | INVALIDREC | ROWNO | ERRORDATA | ERRORMESSAGE   
FileA    |   4      |    4     |     0      | null  | null      | null 
FileB    |   3      |    1     |     2      | 1     |blah blah..| manatory field is blank 
FileB    |   3      |    1     |     2      | 3     |blah blah..| date format is wrong 

但是我需要如下结果集。

预期结果

FILENAME |TOTALREC|VALIDREC|INVALIDREC|ROWNO| ERRORDATA | ERRORMESSAGE   
FileA    |   4    |    4   |    0     | null| null      | null 
FileB    |   3    |    1   |    2     | 1   |blah blah..| manatory field is blank 
         |        |        |          | 3   |blah blah..| date format is wrong 

(注意最后一行的前四列。)

如果可以,谁能帮我查询一下?

更新: 按照你们中许多人的要求澄清我的要求。

看不到 SQL 你在那里使用了什么,但作为一般规则,如果你有类似的东西:

CASE WHEN RANK() OVER (PARTITIION BY a.filename ORDER BY a.rowno DESC) = 1 THEN <insert column here> END

它将根据每个文件中的第一行等过滤掉重复项

在 SQL 服务器中,这确实提供了一种将掩码应用于某些记录而不是其他记录的方法。

COALESCE 就是你想要的。

Select t.myfield, coalesce(t2.Myfield2, '') 
from mytable t
left join mytable2 t2 on t.mytableid = t2.mytableid

据我了解,如果某些字段与上一行中的相应字段相同,您希望将其留空?

无法直接在 MySQL 中执行此操作。您最好使用应用程序语言(PHP、VB、Java 等)。

可以使用@variables、IF()函数调用和ORDER BY.

来做到这一点

首先感谢大家的帮助。

@Rick --> 这是可能的。

一段时间以来,我一直在寻找 H2 数据库特有的解决方案。但是尽管如此,该解决方案应该适用于大多数支持 ranking 或任何实现该功能的数据库。我在这个 Whosebug link.

中找到了 ranking 方法

之后就是小菜一碟了!!

这里是解答问题,有兴趣的朋友们,-

select 
case when (final.INVALIDREC>0 and final.ranking>1) then '' else final.FileName end as FileName,
case when (final.INVALIDREC>0 and final.ranking>1) then '' else cast(final.TOTALREC as varchar(50)) end as TOTALREC,
case when (final.INVALIDREC>0 and final.ranking>1) then '' else cast(final.VALIDREC as varchar(50)) end as VALIDREC,
case when (final.INVALIDREC>0 and final.ranking>1) then '' else cast(final.INVALIDREC as varchar(50)) end as INVALIDREC, final.Rowno , final.ErrorData , final.ErrorMessage
from
(select 
   (
    select  count(*)
    from    (select distinct t1.FILENAME, t2.Rowno from table1 t1
    left outer join table2 t2 on t1.fileid=t2.fileid 
    order by t1.FILENAME) yt2
    where   yt2.FILENAME = temp.FILENAME -- Same partition
            and yt2.Rowno <= temp.Rowno -- Lower or equal rank
    ) as ranking,
temp.FILENAME,temp.TOTALREC, temp.VALIDREC,temp.INVALIDREC, temp.Rowno , temp.ErrorData , temp.ErrorMessage
from
(select distinct t1.FILENAME,tot.TOTALREC, VALIDREC,coalesce((tot.TOTALREC- VALIDREC),0)INVALIDREC, t2.Rowno , case when coalesce((tot.TOTALREC- VALIDREC),0)=0 then null else t1.filedata end as ErrorData , t2.errormsg as ErrorMessage
from table1 t1
join (select count(*) totalrec, fileid from table1 group by fileid)tot on t1.fileid=tot.fileid
join (select count(*) VALIDREC , fileid from table1 where valid=true group by fileid)valid on t1.fileid=valid.fileid
left outer join table2 t2 on t1.fileid=t2.fileid 
order by t1.FILENAME, t2.rowno) temp)final;

这将给出预期结果

*谢谢大家..这是我第一次 post 在 Stack Overflow 中,得到这么多帮助我感到很谦虚..

编码愉快!!*