2016-05-12 210 views
4

使用MSSQL集结SQL结果,两个表,然后汇总结果

我有用户表,和产品表它们认购。这些订阅是免费(F)或付费(P)。我已经加入了这些表格,使用case语句将F/P值转换为数字,然后通过用户ID汇总这些值,想法是任何只有免费账户的人都会有0的总和,至少有一个付费帐户价值1或更高。我用下面的远获得这样的:

SELECT t1.user_id, SUM(
    CASE 
     WHEN t2.free_paid = 'P' 
      THEN 1 
     ELSE 0 
    END) as highest 
FROM users t1 INNER JOIN accounts t2 
    ON t1.user_id = t2.user_id 
WHERE t2.account = 'A' 
GROUP BY t1.user_id 
ORDER BY t1.user_id 

这将产生类似的结果:

755 2 
1259 2 
2031 1 
3888 0 

这意味着所有的,但3888至少有一个支付账户。

但是现在我想简单地添加这些数据来获得我们的两个值,一个是至少有一个付费账户的用户数(例如3个),另一个是只有免费账户的用户数例)。

我试过声明两个变量,例如: @free和@paid,并使用case语句将这些值包装到子查询中,然后将其作为子查询添加到这些值中,但无法运行。

任何想法?

+1

预期结果是什么? –

+0

对于上面的数据,付费:3,免费:1 – SwS

回答

3

重新使用查询从这个问题您可以创建一个CTE(或子查询),并汇总结果:

;WITH CTE_UserAccounts AS (
    SELECT t1.user_id, SUM(
     CASE 
      WHEN t2.free_paid = 'P' 
       THEN 1 
      ELSE 0 
     END) as highest 
    FROM users t1 INNER JOIN accounts t2 
     ON t1.user_id = t2.user_id 
    WHERE t2.account = 'A' 
    GROUP BY t1.user_id 
) 
SELECT 
    COUNT(CASE WHEN highest > 0 THEN 1 END) AS [Paid], 
    COUNT(CASE WHEN highest = 0 THEN 1 END) AS [Free] 
FROM 
    CTE_UserAccounts; 
+0

这也适用,我很欣赏使用CTE解决这个问题的见解。 – SwS

1
SELECT 
COUNT(DISTINCT CASE WHEN t2.free_paid = 'P' THEN t1.user_id END) as atleast_one_paid, 
COUNT(DISTINCT CASE WHEN t2.free_paid <> 'P' THEN t1.user_id END) as onlyfree 
FROM users t1 
INNER JOIN accounts t2 ON t1.user_id = t2.user_id 
WHERE t2.account = 'A' 
+0

实际上,'onlyfree'将是至少有一个免费账户的不同用户的数量,因为没有什么可以阻止查询对至少有一个免费账户的用户进行计数并在两列中至少有一个付费帐户。 –

1

你可以只环绕你的原始查询和概括起来

SELECT SUM (case when highest > 0 THEN 1 else 0 END) as UsersWithPaidAccount, 
SUM (case when highest = 0 THEN 1 else 0 END) as UsersWithOnlyFreeAccount 
FROM (SELECT t1.user_id, SUM(
    CASE 
     WHEN t2.free_paid = 'P' 
      THEN 1 
     ELSE 0 
    END) as highest 
FROM users t1 INNER JOIN accounts t2 
    ON t1.user_id = t2.user_id 
WHERE t2.account = 'A' 
GROUP BY t1.user_id) 
as DerivedTable 
+0

这个工程,非常感谢你! – SwS