2012-04-24 9 views
3

に参加するために、1つのまたは多くの行を選択しTSQLこれはに似質問です

ORDER_ID CODE1 CODE2 CODE3 STATUS TYPE  SUM  GROUP 
1   '001' 'BIGP' NULL 4   'company' 120  48 
2   '002' 'BIGP' NULL 1   'priv'  100  20 
3   '001' NULL NULL 6   'priv'  50  49 
4   '002' NULL 'L'  1   'company' 1253  22 

とそのような第二のテーブル:

ADDRESS_ID ORDER_ID ZIP  TYPE ADD_DATE  CATEGORY  VERIFIED 
1   1   '15-125' 'K1' '2010-01-01' 'CLIENT'  1 
2   1   '22-022' 'D1' '2010-01-02' 'SYSTEM'  1 
3   2   '16-159' 'D2' '2010-01-02' 'SYSTEM'  1 
4   2   '15-125' 'D2' '2010-02-01' 'CLIENT'  0 

第三及び第四の表は、郵便番号などのような都市名が含まれています

'002' 及び '005'
  • (CODE2 = NULLとCODE3 = NULL)又は(間(4,6)
  • CODE1に

    • ステータスをしていないすべての注文のため
      ZIP  CITY 
      '15-125' 'Warszawa' 
      '22-022' 'Koszalin' 
      '16-159' 'Krakow' 
      '15-125' 'Lublin' 
      

      (code2 = NULLおよびcode3 = 'L')

    code1 = '002' AND group(48,59,60、 87)私は単一のアドレスを選択する必要があります
    (Nikola Markovinoに大きな感謝VIC):トップの基準を満たし、=「002」ANDグループNOT IN(48,59,60,87)をCODE1てしまった他のすべてのご注文の場合

    SELECT TOP 1000 o.order_Id 
           , a.Address_Id 
           , a.Zip 
          --, * 
    FROM orders o 
    CROSS APPLY 
    (
    select TOP 1 
         a.Address_Id, 
         a.Zip 
        from address a 
        WHERE a.order_Id = o.order_Id 
        ORDER BY case a.Type 
           when 'D2' then 1 
           when 'K1' then 2 
           else 3 
          end, 
         a.ADD_DATE 
    ) a 
    WHERE 
    o.Status NOT IN (4, 6) 
    AND code1='002' 
    AND group IN (48,59,60,87) 
    AND ((code2 IS NULL AND code3 IS NULL) OR (code2 IN ('BIGA', 'BIGP') AND code3 IS NULL) OR (code2 IS NULL AND code3 = 'L')) 
    

    私が確認したものを注文のすべてのアドレスを選択する必要があります=私は特定の郵便会社は、私はすべての労働組合を作っ考えていたこれらのアドレス(私は郵便番号を含む別のテーブルにチェックされます)

    に自分のメールを配信することができますかどうかを確認することができますこれらのアドレスを収集した後1

    、最初にcode1 = '002'とグループNOT IN(48,59,60,87)のすべてのアドレスを返します。

    しかし、組合なしですべて行うことは可能でしょうか?

    これは私が取得したいと思い、最終的な結果をIT:

    CODE1  TYPE  COUNT_OF_ORDERS  COUNT_OF_ADDRESSES  COMPANY1 OTHER 
    '001'  'NORMAL' 125     150     110  40 
    '002'  'NORMAL' 100     122     100  22 
    '003'  'NORMAL' 150     110     100  10 
    '004'  'NORMAL' 200     220     220  0 
    '005'  'NORMAL' 220     240     210  30 
    '005'  'PRIORITY' 100     110     110  0 
    'SX1'  'PRIORITY' 100     100     20  80 
    

    順のため、そのアドレスは、それが型を持つ場合、通常の郵便番号を持つテーブルに存在するのであれば、私のタイプは「正常」である場合、私は確認する必要があります'priority'私は優先順位コードでテーブルをチェックインする必要があります。

    コードが特定のテーブルに存在する場合は、COMPANY1列に+1を追加します(OTHER以外の場合)。これらの列の合計は自分のアドレスの合計でなければなりません。


    この

    は、あなたが簡単にアドレスをフィルタリングするかもしれない

    SELECT TOP 1000 o.order_Id 
           , a.Address_Id 
           , a.Zip 
          --, * 
    FROM orders o 
    CROSS APPLY 
    (
    select TOP 1 
         a.Address_Id, 
         a.Zip 
        from address a 
        WHERE a.order_Id = o.order_Id 
        AND code1='002' 
        AND o.[group] IN (48,59,60,87) 
        ORDER BY case a.Type 
           when 'D2' then 1 
           when 'K1' then 2 
           else 3 
          end, 
         a.ADD_DATE 
        UNION ALL 
    select 
         a.Address_Id, 
         a.Zip 
        from address a 
        WHERE a.order_Id = o.order_Id 
        AND ((code1='002' AND o.[group] NOT IN (48,59,60,87)) OR code1 IN ('001', '003', '004', '005')) 
        --I'm not shure of that top line, it work's but mayby it con de written better 
        AND Verified = 1 
    ) a 
    WHERE 
    o.Status NOT IN (4, 6) 
    AND ((code2 IS NULL AND code3 IS NULL) 
        OR (code2 IN ('BIGA', 'BIGP') AND code3 IS NULL) 
        OR (code2 IS NULL AND code3 = 'L')) 
    
  • +0

    集計関数MAX、MIN、SUMなど... – Ben

    答えて

    1

    私は(@NikolaMarkovinovićの助けを借りて)行うことができたクエリ([group] IN (48,59,60,87) OR Verified = 1)が、TOP 1はとんでもない事になるだろう微調整(TOP (case when [group] IN (48,59,60,87) then 1 else (select count(*) from addresses where order_Id = o.order_Id) end)です。だから私は、あなたがunion allを行うだけで住所がためにすることを提案する:

    SELECT TOP 1000 o.order_Id 
           , a.Address_Id 
           , a.Zip 
          --, * 
    FROM orders o 
    CROSS APPLY 
    (
    select TOP 1 
         a.Address_Id, 
         a.Zip 
        from address a 
        WHERE a.order_Id = o.order_Id 
        AND o.[group] IN (48,59,60,87) 
        ORDER BY case a.Type 
           when 'D2' then 1 
           when 'K1' then 2 
           else 3 
          end, 
         a.ADD_DATE 
        UNION ALL 
    select 
         a.Address_Id, 
         a.Zip 
        from address a 
        WHERE a.order_Id = o.order_Id 
        AND o.[group] NOT IN (48,59,60,87) 
        AND Verified = 1 
    ) a 
    WHERE 
    o.Status NOT IN (4, 6) 
    AND code1='002' 
    AND ((code2 IS NULL AND code3 IS NULL) 
        OR (code2 IN ('BIGA', 'BIGP') AND code3 IS NULL) 
        OR (code2 IS NULL AND code3 = 'L')) 
    

    PS順序がアドレスを持っていないかもしれない場合CROSSがOUTで適用置き換えますER APPLY。

    +0

    これは興味深い方法ですが、私の質問では書いていたように、001と005の間のcode1ですべての注文を選択する必要がありますcode1 = '002'で(48,59,60,87)をグループ化する場合は、単一のアドレスのみを選択する必要があります。他のすべての状況では、検証済み= 1のすべてのアドレスを選択する必要があります。したがって、注文にはcode1 = 002がありますが、それには(48,59,60,87)以外のグループが含まれている可能性があります。その注文では、すべての確認済み住所を取得する必要があります。私はあなたのクエリを調整して投稿しようとします:) – Misiu

    +0

    @Misiu素晴らしい、ありがとう。私の心は、この「コーデックはヌルであるかコード化されている...」という複雑な条件をすべて消化することができなかったので、アドレス検索の問題に集中していました。昨日は長い一日でした:-) –

    +0

    もう一度ありがとうございます:)あなたは本当にスキルを持っています。 – Misiu

    関連する問題