选择不在Top'n'中的所有数据为“Other”

时间:2010-12-22 16:39:14

标签: sql sql-server-2005

我希望有人可以指出我在哪里出错了,但是我在过去的30分钟里一直在看这个,而且没有随处可见。

我有一个填充了数据的临时表,前端应用程序无法为我做任何逻辑,所以请原谅表中丑陋的case语句逻辑。

当我获得前10名记录时,用户对结果集感到满意。他们现在已经决定要将剩下的一组国家(不排在前10名的所有国家)视为“其他”。

我曾尝试创建一组不在前10名但却没有工作的国家,我正在计划将这一结果提升到前10名。

SELECT c.Country, count(*) AS 'Total_Number_of_customers', COALESCE(ili.new_customers,0) AS 'New_Customers', COALESCE(ilb.existing_first,0) AS 'Existing_First_Trans', COALESCE(ilc.existing_old,0) AS 'Existing_Prev_Trans'
FROM #customer_tmp c 
LEFT JOIN (SELECT z.country, count(*) AS 'new_customers' FROM #customer_tmp z where z.customer_type='New_Customer' group by z.country)ili ON ili.country = c.country
LEFT JOIN (SELECT zy.country, count(*) AS 'existing_first' FROM #customer_tmp zy where zy.customer_type='Existing_Customer' AND zy.first_transaction=1 group by zy.country)ilb ON ilb.country = c.country
LEFT JOIN (SELECT zx.country, count(*) AS 'existing_old' FROM #customer_tmp zx where zx.customer_type='Existing_Customer' AND zx.first_transaction=0 group by zx.country)ilc ON ilc.country = c.country
GROUP BY c.country, ili.new_customers, ilb.existing_first, ilc.existing_old
ORDER BY 2 DESC

这是我用来从我的表中获取结果的SQL。

作为参考,我临时表中的每一行都包含一个客户ID,它们的创建日期和客户类型,这些都是我想要实现的目标。

希望这是一个简单的问题,我只是有点慢......

非常感谢Adv。

4 个答案:

答案 0 :(得分:3)

使用EXCEPT operator in SQL Server

SELECT <fields>
FROM <table>
WHERE <conditons>
EXCEPT
<Query you want excluded>

答案 1 :(得分:2)

烨;除了,或者可能在查询中添加行号,然后选择:

SELECT * FROM (

SELECT c.Country, count(*) AS 'Total_Number_of_customers', 
row_number() OVER (ORDER BY COUNT(*) DESC) AS 'r',
COALESCE(ili.new_customers,0) AS 'New_Customers', COALESCE(ilb.existing_first,0) AS 'Existing_First_Trans', COALESCE(ilc.existing_old,0) AS 'Existing_Prev_Trans'
FROM #customer_tmp c 
LEFT JOIN (SELECT z.country, count(*) AS 'new_customers' FROM #customer_tmp z where z.customer_type='New_Customer' group by z.country)ili ON ili.country = c.country
LEFT JOIN (SELECT zy.country, count(*) AS 'existing_first' FROM #customer_tmp zy where zy.customer_type='Existing_Customer' AND zy.first_transaction=1 group by zy.country)ilb ON ilb.country = c.country
LEFT JOIN (SELECT zx.country, count(*) AS 'existing_old' FROM #customer_tmp zx where zx.customer_type='Existing_Customer' AND zx.first_transaction=0 group by zx.country)ilc ON ilc.country = c.country
GROUP BY c.country, ili.new_customers, ilb.existing_first, ilc.existing_old
ORDER BY 2 DESC

) sub_query WHERE sub_query.r >= 10

这可能更灵活,因为您可以运行一个查询,然后将结果分成“十大”和“其余”非常容易。

(这相当于鲍勃的答案;我想我们正在同时处理这个问题!)

答案 2 :(得分:2)

这是一种使用公用表表达式(CTE)的方法

WITH CTE AS
    (
    SELECT c.Country, count(*) AS 'Total_Number_of_customers', COALESCE(ili.new_customers,0) AS 'New_Customers', COALESCE(ilb.existing_first,0) AS 'Existing_First_Trans', COALESCE(ilc.existing_old,0) AS 'Existing_Prev_Trans'
        , ROW_NUMBER() OVER (ORDER BY count(*) DESC) AS sequence
    FROM #customer_tmp c 
    LEFT JOIN (SELECT z.country, count(*) AS 'new_customers' FROM #customer_tmp z where z.customer_type='New_Customer' group by z.country)ili ON ili.country = c.country
    LEFT JOIN (SELECT zy.country, count(*) AS 'existing_first' FROM #customer_tmp zy where zy.customer_type='Existing_Customer' AND zy.first_transaction=1 group by zy.country)ilb ON ilb.country = c.country
    LEFT JOIN (SELECT zx.country, count(*) AS 'existing_old' FROM #customer_tmp zx where zx.customer_type='Existing_Customer' AND zx.first_transaction=0 group by zx.country)ilc ON ilc.country = c.country
    GROUP BY c.country, ili.new_customers, ilb.existing_first, ilc.existing_old
    )

SELECT *
FROM CTE
WHERE sequence > 10
ORDER BY sequence

答案 3 :(得分:1)

SELECT  country, COUNT(*) cnt, SUM(new_customer), SUM(existing_first_trans), SUM(existing_prev_trans)
FROM    (
        SELECT  CASE
                WHEN country IN
                (
                SELECT  TOP 10 country
                FROM    #customer_tmp
                ORDER BY
                        COUNT(*) DESC
                ) THEN
                        country
                ELSE    'Others'
                END AS country,
                CASE WHEN customer_type = 'New_Customer' THEN 1 END AS new_customer,
                CASE WHEN customer_type = 'Existing_Customer' AND first_transaction = 1 THEN 1 AS existing_first_trans,
                CASE WHEN customer_type = 'Existing_Customer' AND first_transaction = 0 THEN 1 AS existing_prev_trans,
        FROM    #customer_tmp
        )
GROUP BY
        country
ORDER BY
        CASE country WHEN 'Others' THEN 2 ELSE 1 END, cnt DESC