8

我需要对数据库中的各种表执行一些计数,
并且我想将这些计数组合成一个结果。

考虑以下查询:

SELECT 100 As SomeCount
SELECT 200 As SomeOtherCount
SELECT 300 As YetAnotherCount

如果我使用 将它们组合在一起UNION,则每个结果都将成为最终结果中的一行:

SELECT 100 As SomeCount
UNION
SELECT 200 As SomeOtherCount
UNION
SELECT 300 As YetAnotherCount

输出:

> SomeCount
> --------- 
> 100 
> 200 
> 300

我想要的是

> SomeCount | SomeOtherCount | YetAnotherCount
> --------------------------------------------
>   100     |      200       |     300

我可以想到“命名”结果的唯一另一种方法是使用这样的东西:

SELECT 'SomeCount' As Name, 100 As Value
UNION ALL
SELECT 'SomeOtherCount', 200
UNION ALL
SELECT 'YetAnotherCount', 300

在这种情况下,结果如下所示:

>     Name          |      Value
> ---------------------------------
> 'SomeCount'       |       100
> 'SomeOtherCount'  |       200
> 'YetAnotherCount' |       300

有没有办法得到我想要的结果,或者最后一种方法是要走的路?

为了解释核心问题,我应该提到上面的查询非常简单。实际上,需要合并的两个查询可能如下所示:

查询一:

SELECT Count(Id) As UndeliveredSms
FROM
(
 SELECT Id
 FROM IncomingSms
 WHERE Id NOT IN (SELECT IncomingSmsId
                  FROM DeliveryAttempt
                  WHERE Status = 'Delivered' OR Status = 'FailedPermanently')
 )

查询 2:

SELECT Count(Id) As UndeliveredEMail FROM
(
 SELECT Id
 FROM IncomingEMail
 WHERE Id NOT IN (SELECT IncomingEMailId
                  FROM DeliveryAttempt
                  WHERE Status = 'Delivered' OR Status = 'FailedPermanently')
)

将这些包装在另一个SELECT语句中不适用于 SQlite。

使用示例中的最后一种方法确实有效,除非这是一个坏主意,否则我可能会采用该解决方案:

SELECT 'UndeliveredSms' As Name,  Count(Id) As Value
FROM
(
 SELECT Id
 FROM IncomingSms
 WHERE Id NOT IN (SELECT IncomingSmsId
                  FROM DeliveryAttempt
                  WHERE Status = 'Delivered' OR Status = 'FailedPermanently')
 )

UNION

SELECT 'UndeliveredEMail', Count(Id) FROM
(
 SELECT Id
 FROM IncomingEMail
 WHERE Id NOT IN (SELECT IncomingEMailId
                  FROM DeliveryAttempt
                  WHERE Status = 'Delivered' OR Status = 'FailedPermanently')
)

结果是这样的:

>     Name           |     Value
> ---------------------------------
> UndeliveredEMail   |       82
> UndeliveredSms     |       0

当然,在现实中,还有很多事情要计算

4

2 回答 2

4

您应该能够在查询之间使用 CROSS JOIN:

SELECT *
FROM
(
  SELECT Count(Id) As UndeliveredSms
  FROM
  (
   SELECT Id
   FROM IncomingSms
   WHERE Id NOT IN (SELECT IncomingSmsId
                    FROM DeliveryAttempt
                    WHERE Status = 'Delivered' OR Status = 'FailedPermanently')
  )
)
CROSS JOIN
(
  SELECT Count(Id) As UndeliveredEMail FROM
  (
   SELECT Id
   FROM IncomingEMail
   WHERE Id NOT IN (SELECT IncomingEMailId
                    FROM DeliveryAttempt
                    WHERE Status = 'Delivered' OR Status = 'FailedPermanently')
  )
);

请参阅带有演示的 SQL Fiddle

于 2013-07-16T04:03:52.543 回答
2

我不明白UNION您的查询中使用的,但也许我误解了。不在子集联合中 不在所有 = 不在子集中...

似乎可以简化为以下内容:

select *
from
(
  SELECT Count(Id) As UndeliveredSms
  FROM IncomingSms
  WHERE Id NOT IN (SELECT IncomingSmsId
                    FROM DeliveryAttempt
                    WHERE Status = 'Delivered' OR Status = 'FailedPermanently')
) t, 
(
  SELECT Count(Id) As UndeliveredEMail 
  FROM IncomingEMail
  WHERE Id NOT IN (SELECT IncomingEMailId
                    FROM DeliveryAttempt
                    WHERE Status = 'Delivered' OR Status = 'FailedPermanently')
  ) t2
于 2013-07-16T04:25:01.263 回答