5

I have a database table with the following kind of data data

 S_Acc_RowID   BU_Customer_Segment        PBU

 1111-00      PSG SMB       -1
 1111-00      SMB           -1
 1111-00      EB Seg         1
 1111-01      PSG SMB        1 
 1111-01      SMB           -1
 1111-01      EB data       -1
 1111-02      PSG Seg       -1
 1111-02      Unattended    -1
 1111-02      Channels      -1

---------------- like 7 million rows

now I want to extract single row for each Acc ID where the conditions are

1) if the **Acc ID** is having 'EB --' in **CustSeg** then select that **CustSeg** value
2) if **Acc Id** is not having any 'EB -- ' in CustSeg then select **CustSeg** where **PBU** = 1
3) if the both above failed take any one value of the **CustSeg**

and the end data I want should be like

  S_Acc_RowID    BU_Customer_Segment   

   1111-00      EB seg
   1111-01      EB Data
   1111-02      (any one of three[PSG seg/ UNattended/channels])

I'm using the following query

select 
distinct(A.[S_Acc_RowID]) as [Account_RowID],
[EB Customer Segment] =
case
  when LEFT(A.[BU_Customer_Segment],2) = 'EB' then A.[BU_Customer_Segment]
     when LEFT(A.[BU_Customer_Segment],2) != 'EB' then 
          (select B.[BU_Customer_Segment] from 
               dbo.[SiebelAccount Extract] B
               where A.[S_Acc_RowID]=B.[S_Acc_RowID]
               and [PBU] = 1)
 else A.[BU_Customer_Segment]
 end, 
 A.[S_Acc_AMID2#] as [AMID Level 2(Acc)],
 A.[S_Acc_Login_P] as [Sales Team(Acc)], 
 A.[S_Acc_Org_P] as [Country_det],
 A.[Customer AMID Level 2 Name(ACC)] 

 from dbo.[SiebelAccount Extract] A 

But it is returning the the data like this

S_Acc_RowID    BU_Customer_Segment   

   1111-00      EB seg
   1111-01      PSG SMB
   1111-01      EB Data
   1111-02      null

I don't want to display two rows for the ID 1111-01 ..I want only one row with EB

please help me with this ..

Thanks in advance..

Cheers,
Harish

harry
  • 310
  • 1
  • 4
  • 17

1 Answers1

6

On Oracle, i tried the following and it should work if you convert the oracle specific analytic functions, also i made some changes in the sample data for a better example :

    WITH t AS (
    SELECT '1111-00' AS acc_id, 'PSG SMB' AS cust_seg, -1 AS pbu FROM dual UNION ALL
    SELECT '1111-00' AS acc_id, 'SMB'     AS cust_seg, -1 AS pbu FROM dual UNION ALL
    SELECT '1111-00' AS acc_id, 'EB Seg'  AS cust_seg,  1 AS pbu FROM dual UNION ALL
    SELECT '1111-01' AS acc_id, 'PSG SMB' AS cust_seg,  1 AS pbu FROM dual UNION ALL
    SELECT '1111-01' AS acc_id, 'SMB'     AS cust_seg, -1 AS pbu FROM dual UNION ALL
    SELECT '1111-01' AS acc_id, 'Ex data' AS cust_seg, -1 AS pbu FROM dual UNION ALL
    SELECT '1111-02' AS acc_id, 'PSG Seg' AS cust_seg, -1 AS pbu FROM dual UNION ALL
    SELECT '1111-02' AS acc_id, 'Unatten' AS cust_seg, -1 AS pbu FROM dual UNION ALL
    SELECT '1111-02' AS acc_id, 'Channels'AS cust_seg, -1 AS pbu FROM dual )
    --
    SELECT acc_id,
           cust_seg
      FROM (SELECT t.*,
                   row_number() OVER(PARTITION BY acc_id ORDER BY CASE WHEN cust_seg LIKE '%EB%' THEN 1 WHEN pbu = 1 THEN 2 ELSE 3 END ) rnk
              FROM t
             ORDER BY acc_id, CASE WHEN cust_seg LIKE '%EB%' THEN 1 WHEN pbu = 1 THEN 2 ELSE 3 END)
     WHERE rnk = 1 ;

Result :

    ACC_ID                CUST_SEG
    --------------------- ------------------------
    1111-00               EB Seg
    1111-01               PSG SMB
    1111-02               PSG Seg

SQL Server version

    SELECT  *
    FROM    (
              SELECT  *
                      , rn = ROW_NUMBER() OVER (PARTITION BY S_Acc_RowID ORDER BY CASE WHEN LEFT(a.BU_Customer_Segment, 2) = 'EB' THEN 1 WHEN a.PBU = 1 THEN 2 ELSE 3 END)          
              FROM    [SiebelAccount Extract] a
            ) q
    WHERE   rn = 1

and testdata

;WITH [SiebelAccount Extract] (S_Acc_RowID, BU_Customer_Segment, PBU) AS (
  SELECT * FROM (VALUES 
     ('1111-00', 'PSG SMB',  -1)
     , ('1111-00', 'SMB',      -1)
     , ('1111-00', 'EB Seg',    1)
     , ('1111-01', 'PSG SMB',   1)
     , ('1111-01', 'SMB',      -1)
     , ('1111-01', 'EB data',  -1)
     , ('1111-02', 'PSG Seg',  -1)
     , ('1111-02', 'Unattended', -1)
     , ('1111-02', 'Channels', -1)
  ) a (b, c, d)
)
SELECT  *
FROM    (
          SELECT  *
                  , rn = ROW_NUMBER() OVER (PARTITION BY S_Acc_RowID ORDER BY CASE WHEN LEFT(a.BU_Customer_Segment, 2) = 'EB' THEN 1 WHEN a.PBU = 1 THEN 2 ELSE 3 END)          
          FROM    [SiebelAccount Extract] a
        ) q
WHERE   rn = 1
Lieven Keersmaekers
  • 57,207
  • 13
  • 112
  • 146
mcha
  • 2,938
  • 4
  • 25
  • 34
  • +1 SQL Server behaves almost the same. I have a working, almost identical query but you've beaten me by a minute :). – Lieven Keersmaekers Apr 16 '12 at 10:20
  • Hi, Thanks for the reply . But I want the result for 1111-01 as 'EB %', not the PSG one.. And also I have got 7 million rows in my table , so I'm thinking to have a simple query to execute it fast.. – harry Apr 16 '12 at 10:25
  • @harry - mmm, I don't see any immediate error in the query that is posted but I'll append mine wich is giving a correct output. *(you'll notice it's almost the same)* – Lieven Keersmaekers Apr 16 '12 at 10:29
  • @harry : i explicitly changed in the sample data and replaced 'EB data' by 'Ex data' so we can show all of the three possibilities, also this query should be fast enough feel free to try – mcha Apr 16 '12 at 10:30
  • @harry - as for fast, I expect this to be way faster than your original statement *and* it's correct. If a wrong solution is ok, I'm sure I can make it *much* faster :) – Lieven Keersmaekers Apr 16 '12 at 10:33
  • @mcha - I didn't notice the change in the inputs. That explains it offcourse. – Lieven Keersmaekers Apr 16 '12 at 10:34
  • @mcha - I've appended the creation of the testdata as a response to the comments. Feel free to clean it up or remove it completely, it's your answer after all. – Lieven Keersmaekers Apr 16 '12 at 10:36
  • Thank you very much guys ... I have tried it on my database.. thats really quick and giving the exact results which I'm expected... Thakns again to both of you for the quick and accurate response.. :))) – harry Apr 16 '12 at 11:24