5

たとえば、次のデータを含むテーブル(TestFI)があります

FIID   Email
---------
null a@a.com
1    a@a.com   
null b@b.com    
2    b@b.com    
3    c@c.com    
4    c@c.com    
5    c@c.com    
null d@d.com    
null d@d.com

正確に 2 回表示され、かつ FIID が null で 1 行が null でない行が 1 つあるレコードが必要です。上記のデータの場合、「a@a.com と b@b.com」のみが適合します。

私はそのようにマルチレベルのクエリを構築することができました

    Select
FIID,
Email
from
TestFI
where
Email in
(
    Select
        Email
    from
    (
        Select
                Email
            from
                TestFI
            where
                Email in 
                (
                select
                    Email
                from
                    TestFI
                where
                    FIID is null or FIID is not null
                group by Email
                having 
                    count(Email) = 2
                )
                and
                FIID is null
    )as Temp1
    group by Email
    having count(Email) = 1
)

ただし、1,000 万件のレコードを処理するのに 10 分近くかかりました。これを行うより良い方法はありますか?私はここで愚かなことをしているに違いないことを知っています。

ありがとう

4

4 に答える 4

7

私はこのクエリを試してみます:

SELECT   EMail, MAX(FFID)
FROM     TestFI
GROUP BY EMail
HAVING   COUNT(*)=2 AND COUNT(FIID)=1

EMail 列と FFID の null 以外の値を返します。FFID の他の値はヌルです。

于 2013-05-20T22:12:57.007 に答える
1

のインデックスを使用して(email, fid)、次のことを試してみたいと思います。

select  tnull.*, tnotnull.*
from testfi tnull join
     testfi tnotnull
     on tnull.email = tnotnull.email left outer join
     testfi tnothing
     on tnull.email = tnothing.email
where tnothing.email is null and
      tnull.fid is null and
      tnotnull.fid is not null;

パフォーマンスは間違いなくデータベースに依存します。これにより、すべてのアクセスがインデックス内に保持されます。一部のデータベースでは、集計の方が高速な場合があります。パフォーマンスは、クエリの選択性にも依存します。たとえば、1 つの NULL レコードがあり、 index がある場合(fid, email)、これは集計よりもはるかに高速です。

于 2013-05-20T23:23:11.337 に答える
0

多分何か...

select
  a.FIID,
  a.Email

from
  TestFI a
  inner join TestFI b on (a.Email=b.Email)

where
  a.FIID is not null
  and b.FIID is null
;

また、メールと FIID がインデックス化されていることを確認してください。

于 2013-05-20T22:14:23.663 に答える
0

I need records that appear exactly twice AND have 1 row with FIID is null and one is not

1

最も内側の選択で、count = 2 の電子メールでグループ化します。

        select email, coalesce(fiid,-1) as AdjusteFIID from T
        group by email having count(email) =2

2

        select email, AdjustedFIID
        from
        (
          select email, coalesce(fiid,-1) as AdjusteFIID from T
        group by email having count(email) =2
        )  as X
        group by email
        having min(adjustedFIID) = -1 and max(adjustedFIID) > -1
于 2013-05-20T22:40:58.440 に答える