0

次の設定があるとしましょう

MailsTable
Mail1 Varchar(40)
Mail2 Varchar(40)
Mail3 Varchar(40)
Mail4 Varchar(40)

今、空ではない少なくとも 1 つのメール (Mail1 または Mail2... など) を含む行を含むクエリを作成しています。空でないすべてのメールを「;」で連結します。そして、不足している空白文字を埋めて合計 163 文字にします (4 つのメールすべて + ;)

例:

1) Mail1 と Mail3 が存在する行:

george@net.com;louis@net.com
(および 163-28= 135の空白文字で合計 163 文字を埋める)

2) Mail2、Mail3、Mail4 が存在する行:

mail2@gmail.com;mail3@gmail.com;mail4@gmail.com (および 163 を埋めるための多くの空白文字)

しかし、Select を構築しようとすると少しトリッキーになります。CASE WHEN THEN 句を使用することを考えましたが、処理するケースが多すぎます。「空白文字で埋める」問題に伴い。

どんな助けでも大歓迎です。前もって感謝します。

4

3 に答える 3

1

これをテストしていませんが、うまくいくことを願っています。

SELECT ISNULL( Mail1 + ';', '') + ISNULL( Mail2 + ';', '') + ISNULL( Mail3 + ';', '') + ISNULL( Mail4 + ';', '')  AS Result
FROM MailsTable

テーブルに空または空白の文字列がある場合、式はもう少し複雑になります。

SELECT ISNULL( CASE WHEN RTRIM(Mail1) = '' THEN NULL ELSE Mail1 END + ';', '') + 
        ISNULL( CASE WHEN RTRIM(Mail2) = '' THEN NULL ELSE Mail2 END + ';', '') + 
        ISNULL( CASE WHEN RTRIM(Mail3) = '' THEN NULL ELSE Mail3 END + ';', '') + 
        ISNULL( CASE WHEN RTRIM(Mail4) = '' THEN NULL ELSE Mail4 END + ';', '')  AS Result
FROM MailsTable

文字列パディングの要件を逃しました。文字列パディングを使用すると、クエリは次のようになります。

SELECT  CONVERT(CHAR(163), 
        (
            LEFT(
                    ISNULL( CASE WHEN RTRIM(Mail1) = '' THEN NULL ELSE Mail1 END + ';', '') + 
                    ISNULL( CASE WHEN RTRIM(Mail2) = '' THEN NULL ELSE Mail2 END + ';', '') + 
                    ISNULL( CASE WHEN RTRIM(Mail3) = '' THEN NULL ELSE Mail3 END + ';', '') + 
                    ISNULL( CASE WHEN RTRIM(Mail4) = '' THEN NULL ELSE Mail4 END + ';', '') + SPACE(163), 163)
                ))   AS Result 
FROM MailsTable
于 2016-09-22T19:39:52.717 に答える
1

編集 空白、null、および空の文字列を同じように扱うように変更されました。セミコロンを前に置くようにジョーに注意してください。それを行うと、 stuff を使用して空白文字に置き換えることができます。CHAR(163) へのキャストは、文字列の右側を 163 文字の長さに自動的に埋め込みます。

SELECT
    *
    ,CAST(
       STUFF(
          CASE WHEN COALESCE(RTRIM(Mail1),'') <> '' THEN ';' + Mail1 ELSE '' END
          + CASE WHEN COALESCE(RTRIM(Mail2),'') <> '' THEN ';' + Mail2 ELSE '' END
          + CASE WHEN COALESCE(RTRIM(Mail3),'') <> '' THEN ';' + Mail3 ELSE '' END
          + CASE WHEN COALESCE(RTRIM(Mail4),'') <> '' THEN ';' + Mail4 ELSE '' END
       ,1,1,'')
    AS CHAR(163))
FROM
    @MailsTable
WHERE
    COALESCE(RTRIM(Mail1),'') <> ''
    OR COALESCE(RTRIM(Mail2),'') <> ''
    OR COALESCE(RTRIM(Mail3),'') <> ''
    OR COALESCE(RTRIM(Mail4),'') <> ''

テストデータは次のとおりです。

DECLARE @MailsTable AS TABLE (Id INT IDENTITY(1,1), Mail1 VARCHAR(40), Mail2 VARCHAR(40), Mail3 VARCHAR(40), Mail4 VARCHAR(40))
INSERT INTO @MailsTable VALUES
('Mail1@M1.Com','Mail2@M2.Com','Mail3@M3.com','Mail4@M4.com')
,(NULL,'Mail2@M2.Com','Mail3@M3.com','Mail4@M4.com')
,('Mail1@M1.Com',NULL,'Mail3@M3.com','Mail4@M4.com')
,('Mail1@M1.Com','Mail2@M2.Com',NULL,'Mail4@M4.com')
,('Mail1@M1.Com','Mail2@M2.Com','Mail3@M3.com',NULL)
,('Mail1@M1.Com',NULL,NULL,NULL)
,('Mail1@M1.Com','Mail2@M2.Com',NULL,NULL)
,(NULL,'Mail2@M2.Com',NULL,'Mail4@M4.com')
,(NULL,'Mail2@M2.Com',NULL,NULL)
,('Mail1@M1.Com',NULL,NULL,'Mail4@M4.com')
,(NULL,NULL,NULL,'Mail4@M4.com')
,(NULL,NULL,NULL,NULL)
,(NULL,NULL,NULL,'')
,('Mail1@M1.Com','',NULL,'Mail4@M4.com')
,(' ',NULL,'   ','Mail4@M4.com')
,(NULL,NULL,NULL,'   ')
于 2016-09-22T19:46:08.950 に答える
1

これらを最大 163 文字までパディングする理由がよくわかりませんが、空アドレスと空でないアドレスのすべての可能な組み合わせを示す例を次に示します。

declare @MailsTable table
(
    RowNumber int,
    Mail1 varchar(40),
    Mail2 varchar(40),
    Mail3 varchar(40),
    Mail4 varchar(40)
);

insert @MailsTable values
    (0, null, null, null, null),
    (1, 'Addr1', null, null, null),
    (2, null, 'Addr2', null, null),
    (3, 'Addr1', 'Addr2', null, null),
    (4, null, null, 'Addr3', null),
    (5, 'Addr1', null, 'Addr3', null),
    (6, null, 'Addr2', 'Addr3', null),
    (7, 'Addr1', 'Addr2', 'Addr3', null),
    (8, null, null, null, 'Addr4'),
    (9, 'Addr1', null, null, 'Addr4'),
    (10, null, 'Addr2', null, 'Addr4'),
    (11, 'Addr1', 'Addr2', null, 'Addr4'),
    (12, null, null, 'Addr3', 'Addr4'),
    (13, 'Addr1', null, 'Addr3', 'Addr4'),
    (14, null, 'Addr2', 'Addr3', 'Addr4'),
    (15, 'Addr1', 'Addr2', 'Addr3', 'Addr4');

with ConcatenatedAddressesCTE as
(
    select
        RowNumber,
        Mails =
            case when Mail1 != '' then ';' + Mail1 else '' end +
            case when Mail2 != '' then ';' + Mail2 else '' end +
            case when Mail3 != '' then ';' + Mail3 else '' end +
            case when Mail4 != '' then ';' + Mail4 else '' end
    from
        @MailsTable
    where
        Mail1 != '' or Mail2 != '' or Mail3 != '' or Mail4 != ''
)
select
    RowNumber,
    FormattedMails = substring(Mails, 2, 200) + replicate(' ', 164 - len(Mails))
from
    ConcatenatedAddressesCTE;

結果:

RowNumber  FormattedMails
1          Addr1                                                                                                                                                              
2          Addr2                                                                                                                                                              
3          Addr1;Addr2                                                                                                                                                        
4          Addr3                                                                                                                                                              
5          Addr1;Addr3                                                                                                                                                        
6          Addr2;Addr3                                                                                                                                                        
7          Addr1;Addr2;Addr3                                                                                                                                                  
8          Addr4                                                                                                                                                              
9          Addr1;Addr4                                                                                                                                                        
10         Addr2;Addr4                                                                                                                                                        
11         Addr1;Addr2;Addr4                                                                                                                                                  
12         Addr3;Addr4                                                                                                                                                        
13         Addr1;Addr3;Addr4                                                                                                                                                  
14         Addr2;Addr3;Addr4                                                                                                                                                  
15         Addr1;Addr2;Addr3;Addr4                                                                                                                                            

CTE は、すべての空でないアドレスの前にセミコロンを付けて、2 つの空でないアドレスの間にいくつの空のアドレスが発生するかを心配する必要がないようにします。これは、生成されるすべての結果がセミコロンで始まることを意味します。これが、クエリの最後の部分で左端の文字が取り除かれ、長さの計算に 163 ではなく 164 が使用される理由です。

ここで、「空の」メールとは、null または空の文字列のいずれかを意味すると想定しています。

于 2016-09-22T19:41:37.823 に答える