web-dev-qa-db-fra.com

Rejoignez deux requêtes SQL

J'ai deux requêtes SQL, dont la première est:

select Activity, SUM(Amount) as "Total Amount 2009"
from Activities, Incomes
where Activities.UnitName = ? AND
      Incomes.ActivityId = Activities.ActivityID
GROUP BY Activity
ORDER BY Activity;

et le second est:

select Activity, SUM(Amount) as "Total Amount 2008"
from Activities, Incomes2008
where Activities.UnitName = ? AND
      Incomes2008.ActivityId = Activities.ActivityID
GROUP BY Activity
ORDER BY Activity;

(Ne vous occupez pas du '?', Ils représentent un paramètre dans birt). Ce que je veux réaliser est le suivant: Je veux une requête SQL qui renvoie la même chose que la première requête, mais avec une (troisième) colonne supplémentaire qui ressemble exactement à "Total Amount 2008" (de la 2ème requête).

29
anon

Certains SGBD prennent en charge la syntaxe FROM (SELECT ...) AS alias_name.

Considérez vos deux requêtes d'origine comme des tables temporaires. Vous pouvez les interroger comme ceci:

SELECT t1.Activity, t1."Total Amount 2009", t2."Total Amount 2008"
FROM (query1) as t1, (query2) as t2
WHERE t1.Activity = t2.Activity
46
Liam
SELECT Activity, arat.Amount "Total Amount 2008", abull.Amount AS "Total Amount 2009"
FROM
  Activities a
LEFT OUTER JOIN
  (
  SELECT ActivityId, SUM(Amount) AS Amount
  FROM Incomes ibull
  GROUP BY
    ibull.ActivityId
  ) abull
ON abull.ActivityId = a.ActivityID
LEFT OUTER JOIN
  (
  SELECT ActivityId, SUM(Amount) AS Amount
  FROM Incomes2008 irat
  GROUP BY
    irat.ActivityId
  ) arat
ON arat.ActivityId = a.ActivityID
WHERE a.UnitName = ?
ORDER BY Activity
16
Quassnoi

Je voudrais juste utiliser un nion

Dans votre deuxième requête, ajoutez le nom de colonne supplémentaire et ajoutez un '' dans tous les emplacements correspondants dans les autres requêtes

Exemple

//reverse order to get the column names
select top 10 personId, '' from Telephone//No Column name assigned 
Union 
select top 10 personId, loanId from loan
11
cgreeno

Voici ce qui a fonctionné pour moi:

select visits, activations, simulations, simulations/activations
   as sims_per_visit, activations/visits*100
   as adoption_rate, simulations/activations*100
   as completion_rate, duration/60
   as minutes, m1 as month, Wk1 as week, Yr1 as year 

from
(
    (select count(*) as visits, year(stamp) as Yr1, week(stamp) as Wk1, month(stamp)
    as m1 from sessions group by week(stamp), year(stamp)) as t3

    join

    (select count(*) as activations, year(stamp) as Yr2, week(stamp) as Wk2,
    month(stamp) as m2 from sessions where activated='1' group by week(stamp),
    year(stamp)) as t4

    join

    (select count(*) as simulations, year(stamp) as Yr3 , week(stamp) as Wk3,
    month(stamp) as m3 from sessions where simulations>'0' group by week(stamp),
    year(stamp)) as t5

    join

    (select avg(duration) as duration, year(stamp) as Yr4 , week(stamp) as Wk4,
    month(stamp) as m4 from sessions where activated='1' group by week(stamp),
    year(stamp)) as t6
)
where Yr1=Yr2 and Wk1=Wk2 and Wk1=Wk3 and Yr1=Yr3 and Yr1=Yr4 and Wk1=Wk4

J'ai utilisé des jointures, pas des unions (j'avais besoin de colonnes différentes pour chaque requête, une jointure met tout dans la même colonne) et j'ai laissé tomber les guillemets (par rapport à ce que faisait Liam) parce qu'ils me donnaient des erreurs.

Merci! Je n'aurais pas pu retirer ça sans cette page! PS: Désolé, je ne sais pas comment vous obtenez vos déclarations formatées avec des couleurs. etc.

2
Haitham Alhumsi

Essaye ça:

select Activity, SUM(Incomes.Amount) as "Total Amount 2009", SUM(Incomes2008.Amount) 
as "Total Amount 2008" from
Activities, Incomes, Incomes2008
where Activities.UnitName = ?  AND
Incomes.ActivityId = Activities.ActivityID  AND
Incomes2008.ActivityId = Activities.ActivityID GROUP BY
Activity ORDER BY Activity;

Fondamentalement, vous devez rejoindre la table Incomes2008 avec la sortie de votre première requête.

1
Shivasubramanian A

Si vous supposez que des valeurs existent pour toutes les activités au cours des deux années, effectuez simplement une jointure interne comme suit

 select act.activity, t1.amount as "Total 2009", t2.amount as "Total 2008"
from Activities as act,
    (select activityid,  SUM(Amount) as amount
    from Activities, Incomes
    where Activities.UnitName = ? AND
          Incomes.ActivityId = Activities.ActivityID
    GROUP BY Activityid) as t1,
    (select activityid, SUM(Amount) as amount
    from Activities, Incomes2008
    where Activities.UnitName = ? AND
          Incomes2008.ActivityId = Activities.ActivityID
    GROUP BY Activityid) as t2
    WHERE t1.activityid= t2.activityid
    AND act.activityId = t1.activityId
    ORDER BY act.activity

Si vous ne pouvez pas supposer cela, alors essayez de faire une jointure externe

1
Il-Bhima

peut-être pas la façon la plus élégante de résoudre ce problème

select  Activity, 
        SUM(Amount) as "Total_Amount",
        2009 AS INCOME_YEAR
from    Activities, Incomes
where Activities.UnitName = ? AND
      Incomes.ActivityId = Activities.ActivityID
GROUP BY Activity
ORDER BY Activity;

UNION

select  Activity, 
        SUM(Amount) as "Total_Amount",
        2008 AS INCOME_YEAR
from Activities, Incomes2008
where Activities.UnitName = ? AND
      Incomes2008.ActivityId = Activities.ActivityID
GROUP BY Activity
ORDER BY Activity;
1
Natrium