2013-07-16 8 views
6

Muszę wykonać liczbę zliczeń na różnych tabelach w bazie danych
i chciałbym połączyć te liczby w jeden wynik.Połączyć wiele wyników jako kolumny, a nie wiersze

Conider następujących zapytań:

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

Gdybym połączyć je za pomocą UNION, każdy z wyników będzie wiersz w efekcie końcowym:

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

wyjściowa:

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

Tym, czego chcę, jest

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

Jedynym sposobem mogę myśleć off „nazwa” Wyniki używa coś takiego:

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

W takim przypadku wynik wygląda tak:

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

Czy istnieje sposób na uzyskanie pożądanych rezultatów, lub ostatnia metoda do zrobienia?

Powinienem wspomnieć powyższe zapytania są bardzo proste, aby wyjaśnić podstawowy problem. w rzeczywistości dwoma zapytaniami, które muszą być połączone może wyglądać następująco:

Query 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') 
) 

Query 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') 
) 

Owijanie nich w innym SELECT oświadczenia nie działa z SQLite .

Korzystanie ostatnią metodę w przykładach działa i mogę iść z tego rozwiązania, chyba że jest to zły pomysł:

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') 
) 

co skutkuje coś takiego:

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

I Oczywiście, w rzeczywistości, istnieje o wiele więcej rzeczy do zliczenia

Odpowiedz

4

Powinieneś być w stanie użyć CROSS JOIN między zapytaniami:

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') 
) 
); 

Zobacz SQL Fiddle with Demo

+0

Dziękuję, że rozwiązuje mój problem :-) – TimothyP

+0

@TimothyP Zapraszamy !! – Taryn

+1

Czy w tym przypadku Unia jest konieczna? Wydaje się działać bez względu na charakter dwóch zapytań: http://sqlfiddle.com/#!7/f8ac1/6 – user2480596

1

Nie rozumiem zastosowanie UNION w zapytaniach, ale być może jestem nieporozumienie. Nie w zestawie podzbiorów nie we wszystkich = nie w podzbiorze ...

Wygląda to może być uproszczone do następującego:

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 
+0

Właściwie możesz mieć rację, wcześniej próbowałem go rozwiązać inaczej. Zajrzę do tego, niezły haczyk! – TimothyP

+0

@TymothyP - np - nadzieję, że to pomogło. Bluefeet dostarczył poprawną odpowiedź - to była tylko strona uwaga :) Pozdrawiam! – user2480596