¿Cómo puedo realizar una resta entre los resultados de 2 consultas con un grupo por?

La primera consulta devuelve el número de todos, digamos casas que puedo alquilar, mientras que la segunda devuelve las ya alquiladas.

SELECT
    (SELECT COUNT(*) FROM ... GroupBy ...)
      - (SELECT COUNT(*) FROM ... WHERE ...group by) AS Difference

Primer resultado de la consulta

count() column2    column3
 3       studio     newYork
 6       studio     pekin
 3       apprtment  pekin
 5       house      london
 1       house      lagos

Segundo resultado de la consulta

count() column2    column3
 2       studio     newYork

Me encantaría que la primera consulta se actualice dependiendo del resultado de la segunda

count() column2    column3
 1       studio     newYork
 6       studio     pekin
 3       apprtment  pekin
 5       house      london
 1       house      lagos
2
Sharp 25 dic. 2016 a las 06:06

3 respuestas

La mejor respuesta

¿Cómo puedo realizar una resta entre los resultados de 2 consultas con un grupo por?

Estás cerca de lo que tienes. Sin embargo, hay algunos cambios que facilitarían este trabajo:

  1. Alias los resultados de sus dos subconsultas. Esto los hará más fáciles de usar.
  2. Devuelve más columnas de tus subconsultas para que puedas unirte a "algo" que permitiría que la resta solo ocurra en filas coincidentes.
  3. Agregue un alias a sus declaraciones Count(*). Nuevamente, esto los hará más fáciles de usar.

Si esta imagen muestra lo que está buscando:

Output of the query with the example tables as the data source

Entonces creo que esta consulta te ayudará:

SELECT op.ApartmentType,
    op.ApartmentLocation,
    op.TotalOwned,
    ISNULL(tp.TotalOccupied, 0) AS [TotalOccupied],
    op.TotalOwned - ISNULL(tp.TotalOccupied,0) AS [TotalVacant]
FROM
(
    SELECT *,
        COUNT(*) as TotalOwned
    FROM SO_SubtractionQuestion.OwnedProperties
    GROUP BY ApartmentType, ApartmentLocation
) AS op
LEFT JOIN
(
    SELECT *, 
        COUNT(*) as TotalOccupied
    FROM [SO_SubtractionQuestion].[OccupiedProperties]
    GROUP BY ApartmentType, ApartmentLocation
) AS tp
ON op.ApartmentType = tp.ApartmentType 
    AND op.ApartmentLocation = tp.ApartmentLocation

Configuré esta consulta de manera similar a la suya: tiene una instrucción select con dos subconsultas y las subconsultas tienen un Count(*) en una consulta agrupada. También agregué lo que sugerí anteriormente:

  • Mi primera subconsulta tiene un alias con op (propiedades propias) y mi segunda tiene un alias con tp (propiedades tomadas).
  • Estoy devolviendo más columnas para poder unirlas correctamente en mi consulta externa.
  • Mis declaraciones Count(*) en mis subconsultas tienen alias.

En mi consulta externa, puedo unirme en ApartmentType y ApartmentLocation (consulte a continuación la tabla de ejemplo / configuración de datos). Esto crea un conjunto de resultados que se une en ApartmentType y ApartmentLocation que también contiene cuántas propiedades propias hay (las Count(*) de la primera subconsulta) y cuántas propiedades ocupadas hay (las Count(*) de la segunda subconsulta). En este punto, debido a que tengo todo alias, puedo hacer una resta simple para ver cuántas propiedades están vacantes con op.TotalOwned - ISNULL(tp.TotalOccupied,0) AS [TotalVacant].

También estoy usando ISNULL para corregir valores nulos . Si no tuviera esto, el resultado de la resta también sería nulo para las filas que no coincidían con la segunda subconsulta.

Tabla de prueba / Configuración de datos

Para configurar el ejemplo usted mismo, aquí están las consultas para ejecutar:

Paso 1

Para fines organizativos

CREATE SCHEMA SO_SubtractionQuestion;

Paso 2

CREATE TABLE SO_SubtractionQuestion.OwnedProperties
(
 ApartmentType varchar(20),
 ApartmentLocation varchar(20)
);

CREATE TABLE SO_SubtractionQuestion.OccupiedProperties
(
 ApartmentType varchar(20),
 ApartmentLocation varchar(20)
);

INSERT INTO [SO_SubtractionQuestion].[OwnedProperties] VALUES ('Studio', 'New York'), ('Studio', 'New York'), ('Studio', 'New York'), ('House', 'New York'), ('House', 'Madison');
INSERT INTO [SO_SubtractionQuestion].[OccupiedProperties] VALUES ('Studio', 'New York'), ('Studio', 'New York');
2
Joshua 26 dic. 2016 a las 15:45

Solo use la agregación condicional:

SELECT COUNT(*) -
       SUM(CASE WHEN <some_condition> THEN 1 ELSE 0 END) AS some_count,
       column2,
       column3
FROM yourTable
GROUP BY column2, column3

Aquí <some_condition> es lo que hubiera aparecido en la cláusula WHERE de su segunda consulta de conteo original.

4
Tim Biegeleisen 25 dic. 2016 a las 03:28
Select Column2, Column3, Count(*)-(Select Count(*)
                                   From Table2 
                                   Where Table1.Column2=Table2.Column2 and Table1.Column3=Table2.Column3)
From Table1
Group by Column2, Column3
0
Ric_R 26 dic. 2016 a las 15:07