SQL查询以检索具有所需列值的单行数据
我有一个包含以下数据类型的数据库表SQL查询以检索具有所需列值的单行数据,sql,sql-server,sql-server-2008,group-by,duplicate-removal,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 -
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
请帮我做这个
提前谢谢
干杯,Harish在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
和测试数据
;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
+1 SQL Server的行为几乎相同。我有一个工作,几乎相同的问题,但你已经击败了我一分钟:)。嗨,谢谢你的回答。但我希望1111-01的结果为“EB%”,而不是PSG的结果。。而且我的表中有700万行,所以我想用一个简单的查询来快速执行它。@harry-mmm,我在发布的查询中没有看到任何即时错误,但我会附加我的,因为它给出了正确的输出。(你会注意到这几乎是一样的)@harry:我在示例数据中明确地更改了“EB数据”,并将“EB数据”替换为“Ex数据”,这样我们就可以显示所有这三种可能性,而且这个查询应该足够快,可以随时查询try@harry-至于fast,我希望这比你最初的陈述快得多,这是正确的。如果一个错误的解决方案是可以的,我相信我可以使它更快:)