8

データベース内のさまざまなテーブルで多数のカウントを実行する必要があり、
それらのカウントを 1 つの結果に結合したいと考えています。

次のクエリを検討してください。

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

私が望む結果を得る方法はありますか、それとも最後の方法ですか?

コアの問題を説明するために、上記のクエリは非常に単純です。実際には、組み合わせる必要がある 2 つのクエリは次のようになります。

クエリ 1:

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 に答える