SQL查询,用于检索具有所需列值的单行数据

时间:2012-04-16 09:52:35

标签: sql sql-server sql-server-2008 group-by duplicate-removal

我有一个包含以下数据数据的数据库表

 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

----------------喜欢700万行

现在我想为条件为

的每个Acc ID提取单行
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**

,我想要的最终数据应该是

  S_Acc_RowID    BU_Customer_Segment   

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

我正在使用以下查询

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 

但它正在返回这样的数据

S_Acc_RowID    BU_Customer_Segment   

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

我不想为ID 1111-01显示两行。我只想要一行EB

请帮帮我..

提前致谢..

干杯,
哈里什

1 个答案:

答案 0 :(得分:6)

在Oracle上,我尝试了以下内容,如果你转换oracle特定的分析函数它应该工作,我也在示例数据中做了一些更改,以获得更好的例子:

    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版本

    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

和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