2013-03-15 3 views
1

j'ai une requête comme ceci:requête SQL Server + résultats rejoindre

SELECT recipientid AS ID, 
COUNT(*) AS Recieved FROM Inbox 
GROUP BY recipientid 

UNION 

SELECT SenderId, 
COUNT(*) AS [Sent] FROM Inbox 
GROUP BY SenderId 

La sortie:

RecipientID Recieved 

001    3 
001    4 
002    4 
002    2 
003   18 
003   55 

Comment puis-je réécrire une telle manière qu'il affiche comme ceci:

RecipientID Recieved Sent 

001    3  4 
002    4  2 
003   18  55 

Merci.

+1

Veuillez spécifier le SGBDR que vous ciblez en ajoutant la balise appropriée (Oracle, SQL Server, MySQL, etc.). Il peut y avoir des réponses qui tirent parti des fonctionnalités de langue ou de produit qui ne sont pas prises en charge universellement. En outre, en l'associant à un SGBDR spécifique, votre question peut susciter l'attention de personnes mieux à même d'y répondre. – Taryn

Répondre

3

nous intégrions au Sous-requêtes:

select a.ID,Received,Sent 
from(
    SELECT recipientid AS ID, 
    COUNT(*) AS Recieved FROM Inbox 
    GROUP BY recipientid 
)a 
full outer join(
    SELECT SenderId as ID, 
    COUNT(*) AS [Sent] FROM Inbox 
    GROUP BY SenderId 
)b 
on (a.ID = b.ID) 
order by a.ID; 

Notez que cela saisit toutes les sent et received valeurs pour tous les destinataires ou les expéditeurs. Si vous voulez seulement des résultats pour ID s appartenant à des destinataires et des expéditeurs, faites un inner join.

+0

Vous voulez que ce soit une jointure externe complète, pas une jointure interne, sinon vous n'aurez que les destinataires qui ont envoyé et reçu des messages. – MattW

+0

@MattW - Bon appel (bien que ce n'était pas complètement clair de la question). Lemme edit ... –

+0

Et ID est ambigu dans la première ligne de sélection. – KekuSemau

0

Si c'est Postgres, MS SQL ou d'autres qui prennent en charge CTEs -

With Both as 
(
SELECT 
    recipientid AS ID, 
    Count(*) AS Recieved, 
    0 as [Sent] 
FROM Inbox 
GROUP BY recipientid 
UNION 
SELECT 
    SenderId as ID, 
    0 as Recieved, 
    Count(*) AS [Sent] 
FROM Inbox 
GROUP BY SenderId 
) 
SELECT 
    ID, 
    Sum(Received) as [Received], 
    Sum(Sent) as [Sent] 
FROM BOTH 
GROUP BY ID 
ORDER BY 1 
2

J'ajouterais une colonne source à votre requête et faire un simple pivot

select ID, 
     max (case when source=1 then Cnt else 0 end) as Received, 
     max (case when source=2 then Cnt else 0 end) as Sent 
from (
    SELECT 1 as Source, 
     recipientid AS ID, 
     COUNT(*) AS Cnt 
    FROM Inbox 
    GROUP BY recipientid 
    UNION 
    SELECT 2 as Source, 
     SenderId, 
     COUNT(*) 
    FROM Inbox 
    GROUP BY SenderId 
) x 
GROUP BY ID 
+1

Je pourrais suggérer d'utiliser 'SUM' au lieu de' MAX'. – Taryn

+0

J'y ai pensé et c'est habituellement ce que je fais (SUM au lieu de MAX), mais les deux requêtes internes sont groupées de toute façon donc c'est sûr ... Mais c'est peut-être plus clair ... Aussi, je n'ai même pas besoin de groupe intérieur d'ici là – alzaimar

0

En supposant que vous avez une table users avec les ID, vous pouvez faire quelque chose comme:

SELECT 
    users.id, 
    COUNT(sent.senderid) AS sent, 
    COUNT(received.recipientid) AS received 
FROM 
    users 
    LEFT JOIN inbox AS sent ON sent.senderid = users.id 
    LEFT JOIN inbox AS received ON received.recipientid = users.id 
GROUP BY sent.senderid, received.recipientid 
ORDER BY users.id;