Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQL query to retrieve the single line of data with desired values for the columns

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

like image 881
harry Avatar asked Apr 16 '12 09:04

harry


People also ask

How do I retrieve a specific row in SQL?

To select rows using selection symbols for character or graphic data, use the LIKE keyword in a WHERE clause, and the underscore and percent sign as selection symbols. You can create multiple row conditions, and use the AND, OR, or IN keywords to connect the conditions.

Which method is used to retrieve all rows and single row?

Answer. Answer: A SELECT statement retrieves zero or more rows from one or more database tables or database views. In most applications, SELECT is the most commonly used data manipulation language (DML) command.


1 Answers

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
like image 132
mcha Avatar answered Nov 09 '22 23:11

mcha