5

Tengo una tabla de base de datos con el siguiente tipo de datos de datosconsulta SQL para recuperar la línea única de los datos con los valores deseados para las columnas

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 

---------- ------ como 7 millones de filas

ahora quieren extraer una sola fila para cada ID Acc donde las condiciones son

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** 

y los datos finales que quiero debe ser como

S_Acc_RowID BU_Customer_Segment 

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

estoy usando la siguiente consulta

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 

Pero es devolver los datos como éste

S_Acc_RowID BU_Customer_Segment 

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

No quiero mostrar dos filas para la ID 1111-01. Solo quiero una fila con EB

favor me ayude con esto ..

Gracias de antemano ..

Cheers,
Harish

Respuesta

6

En Oracle, he intentado lo siguiente y que debería funcionar si convierte el oráculo funciones analíticas específicas, también hice algunos cambios en los datos de muestra para un mejor ejemplo:

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 versión

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 

y 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 
+0

+1 SQL Server se comporta casi igual. Tengo una consulta de trabajo, casi idéntica, pero me has vencido por un minuto :). –

+0

Hola, gracias por la respuesta. Pero quiero el resultado para 1111-01 como 'EB%', no para PSG ... Y también tengo 7 millones de filas en mi tabla, así que estoy pensando en tener una consulta simple para ejecutarla rápidamente .. – harry

+0

Gracias Lieven =) – mcha

Cuestiones relacionadas