How to use multiple selects in same query without messing everything

冷暖自知 提交于 2021-01-29 09:04:50

问题


So, i have this query

  SELECT nome_equipa,
  count(id_golo) AS golos_marcados FROM equipa,golo 
  WHERE golo.equipa_id_equipa = id_equipa 
  GROUP BY golo.equipa_id_equipa, nome_equipa ORDER BY count(id_golo)DESC

which outputs this table

then i have this other query

SELECT nome_equipa,
       sum(CASE
               WHEN (resultado_visitado = resultado_visitante)
                    AND jogo.equipa_id_equipa = id_equipa
                    OR (resultado_visitante = resultado_visitado)
                    AND jogo.equipa_id_equipa1 = id_equipa THEN 1
               ELSE 0
           END) AS empates,
       sum(CASE
               WHEN (resultado_visitado > resultado_visitante)
                    AND jogo.equipa_id_equipa = id_equipa
                    OR (resultado_visitante > resultado_visitado)
                    AND jogo.equipa_id_equipa1 = id_equipa THEN 1
               ELSE 0
           END) AS vitorias,
       sum(CASE
               WHEN (resultado_visitado < resultado_visitante)
                    AND jogo.equipa_id_equipa = id_equipa
                    OR (resultado_visitante < resultado_visitado)
                    AND jogo.equipa_id_equipa1 = id_equipa THEN 1
               ELSE 0
           END) AS derrotas
FROM jogo,
     equipa
GROUP BY nome_equipa
ORDER BY vitorias DESC

which outputs this:

All i want to do is place the two columns side by side without bugs.

tried this

select nome_equipa, count(id_golo) as golos_marcados,
sum(case when (resultado_visitado = resultado_visitante) and jogo.equipa_id_equipa = id_equipa or (resultado_visitante = resultado_visitado) and jogo.equipa_id_equipa1 = id_equipa  then 1 else 0 end ) as empates,
sum(case when (resultado_visitado > resultado_visitante) and jogo.equipa_id_equipa = id_equipa or (resultado_visitante > resultado_visitado) and jogo.equipa_id_equipa1 = id_equipa  then 1 else 0 end ) as vitorias,
sum(case when (resultado_visitado < resultado_visitante) and jogo.equipa_id_equipa = id_equipa or (resultado_visitante < resultado_visitado) and jogo.equipa_id_equipa1 = id_equipa  then 1 else 0 end ) as derrotas
from jogo, equipa, golo
where golo.equipa_id_equipa = id_equipa
group by nome_equipa
order by vitorias desc

but it returned this:

Here is the ER diagram:


回答1:


Ok, Is hard to follow up the logic with the above information, so I can't give you the exact query you have to run. But What I can suggest how to arrive to it.

I would recommend to use WITH statement. (https://www.postgresql.org/docs/9.1/queries-with.html)

Sth like:

WITH goals AS (
        SELECT 
        nome_equipa,
        count(id_golo) as golos_marcados 
        FROM equipa, golo 
        WHERE golo.equipa_id_equipa = id_equipa 
        GROUP BY nome_equipa
     )

SELECT nome_equipa,
       g.golos_marcados,
       sum(CASE
               WHEN (resultado_visitado = resultado_visitante)
                    AND jogo.equipa_id_equipa = id_equipa
                    OR (resultado_visitante = resultado_visitado)
                    AND jogo.equipa_id_equipa1 = id_equipa THEN 1
               ELSE 0
           END) AS empates,
       sum(CASE
               WHEN (resultado_visitado > resultado_visitante)
                    AND jogo.equipa_id_equipa = id_equipa
                    OR (resultado_visitante > resultado_visitado)
                    AND jogo.equipa_id_equipa1 = id_equipa THEN 1
               ELSE 0
           END) AS vitorias,
       sum(CASE
               WHEN (resultado_visitado < resultado_visitante)
                    AND jogo.equipa_id_equipa = id_equipa
                    OR (resultado_visitante < resultado_visitado)
                    AND jogo.equipa_id_equipa1 = id_equipa THEN 1
               ELSE 0
           END) AS derrotas
FROM jogo      -- equipa TABLE IS NO NEEDED
LEFT JOIN goals g
ON goals.nome_equipa = jogo.nome_equipa
GROUP BY nome_equipa

Then you join with the other query and by nome_equipa and add the column. And that's it.




回答2:


You can use with as was mentioned above. Also join will give you same results:

select bla, lorum, ipsum from table1
join (select bla, bla1 from table 2) as select_row on select_row.bla = table1.bla



回答3:


Not easy to jump into your project, English would be preferred as stated by Pato Navarro !

First of all, the structure of your queries could be improved, for instance see the manual about the FROM clause and the manual about the window functions. Let's try for the first query (not tested !) :

SELECT e.id_equipa
     , e.nome_equipa
     , count(*) AS golos_marcados
  FROM equipa AS e
 INNER JOIN golo AS g
    ON g.equipa_id_equipa = e.id_equipa 
 GROUP BY g.equipa_id_equipa
 ORDER BY golos_marcados DESC

Let's try for the second query (not tested !) :

SELECT e.id_equipa
     , e.nome_equipa
     , count(*) FILTER (WHEN j.resultado_visitado = j.resultado_visitante) AS empates
     , count(*) FILTER (WHEN (j.equipa_id_equipa = e.id_equipa AND j.resultado_visitado > j.resultado_visitante) OR (j.equipa_id_equipa1 = e.id_equipa AND j.resultado_visitante > j.resultado_visitado)) AS vitorias
     , count(*) FILTER (WHEN (j.equipa_id_equipa = e.id_equipa AND j.resultado_visitado < j.resultado_visitante) OR (j.equipa_id_equipa1 = e.id_equipa AND j.resultado_visitante < j.resultado_visitado)) AS derrotas
  FROM equipa AS e
  LEFT JOIN jogo AS j
    ON j.equipa_id_equipa = e.id_equipa     -- equipa plays at home
    OR j.equipa_id_equipa1 = e.id_equipa    -- equipa plays outside
 GROUP BY e.id_equipa
 ORDER BY vitorias DESC

If both queries run well, then you can merge them together like this (not tested !) :

WITH goal AS (
SELECT e.id_equipa
     , e.nome_equipa
     , count(*) AS golos_marcados
  FROM equipa AS e
 INNER JOIN golo AS g
    ON g.equipa_id_equipa = e.id_equipa 
 GROUP BY g.equipa_id_equipa
 ), result AS (
SELECT e.id_equipa
     , e.nome_equipa
     , count(*) FILTER (WHEN j.resultado_visitado = j.resultado_visitante) AS empates
     , count(*) FILTER (WHEN (j.equipa_id_equipa = e.id_equipa AND j.resultado_visitado > j.resultado_visitante) OR (j.equipa_id_equipa1 = e.id_equipa AND j.resultado_visitante > j.resultado_visitado)) AS vitorias
     , count(*) FILTER (WHEN (j.equipa_id_equipa = e.id_equipa AND j.resultado_visitado < j.resultado_visitante) OR (j.equipa_id_equipa1 = e.id_equipa AND j.resultado_visitante < j.resultado_visitado)) AS derrotas
  FROM equipa AS e
  LEFT JOIN jogo AS j
    ON j.equipa_id_equipa = e.id_equipa     -- equipa plays at home
    OR j.equipa_id_equipa1 = e.id_equipa    -- equipa plays outside
 GROUP BY e.id_equipa
)
SELECT g.id_equipa
     , g.nome_equipa
     , g.golos_marcados
     , r.empates
     , r.vitorias
     , r.derrotas
  FROM goal AS g
 INNER JOIN result AS r
    ON g.id_equipa = r.id_equipa
 ORDER BY g.golos_marcados DESC, r.vitorias DESC

At the end of the story, the main issue is not about your queries, but it is about the structure of your tables : the resultado_visitado and resultado_visitante of the jogo table should be calculated from the table gojo, otherwise your data may be inconsistent !



来源:https://stackoverflow.com/questions/65478460/how-to-use-multiple-selects-in-same-query-without-messing-everything

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!