¿Cómo creo una consulta SQL para tener valores MTD y YTD en la misma fila?

programación


Tengo un Crystal Report que estoy convirtiendo a SSRS actualmente. Este informe tiene 3 columnas para MTD (valores del mes hasta la fecha) y 3 columnas para YTD (valores del año hasta la fecha). Puedo separar esas 3 columnas, pero para la precisión de los datos necesito combinarlas en una declaración SQL para generar en una fila. Pude acercarlo casi usando algunas funciones de fusión en SQL. El problema es que no me deja usar los comandos agrupar por y me arroja un error. ¿Qué debo editar en mi consulta SQL de la forma que se muestra en el siguiente Crystal Report?
Error :

Msg 512, Level 16, State 1, Line 106
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.

Crystal Report actual que estoy convirtiendo a SSRS

EDITAR: Acabo de crear un dbfiddle de muestra: DB Fiddle – Zona de juegos de bases de datos SQL[^]

En el Código 2 he intentado usar algunas uniones con y pero me está dando algún error como

Incorrect syntax near the keyword 'with'. If this statement is a common table expression, an xmlnamespaces clause or a change tracking context clause, the previous statement must be terminated with a semicolon.

Lo que he probado:

Código 1

SQL
SET ARITHABORT OFF
SET ANSI_WARNINGS OFF
SELECT coalesce((Select ((SUM( "IS_vwSalesbyProductLineComp"."sls_amt")-SUM( "IS_vwSalesbyProductLineComp"."cost_amt"))/SUM( "IS_vwSalesbyProductLineComp"."sls_amt"))*100 ),0) AS G1MTD,
	   "IS_vwSalesbyProductLineComp"."Mainslspsn_name",
	   "IS_vwSalesbyProductLineComp"."PCSummarized",
	   coalesce ((SELECT SUM("IS_vwSalesbyProductLineComp"."qty_to_ship"-"IS_vwSalesbyProductLineComp"."qty_return_to_stk")FROM "100"."dbo"."IS_vwSalesbyProductLineComp"
   where Year = 2021
   and Month between 1 and 12 Group by Mainslspsn_name,PCSummarized),0) AS Qty_Sold,
	   coalesce ((SELECT SUM("IS_vwSalesbyProductLineComp"."sls_amt")FROM "100"."dbo"."IS_vwSalesbyProductLineComp"
   where Year = 2021
   and Month between 1 and 12 Group by Mainslspsn_name,PCSummarized),0) AS YTD_Sales,
	   coalesce ((SELECT SUM("IS_vwSalesbyProductLineComp"."cost_amt")FROM "100"."dbo"."IS_vwSalesbyProductLineComp"
   where Year = 2021
   and Month between 1 and 12 Group by Mainslspsn_name,PCSummarized),0) AS YTD_COGS,
	   coalesce((Select ((SUM( "IS_vwSalesbyProductLineComp"."sls_amt")-SUM( "IS_vwSalesbyProductLineComp"."cost_amt"))/SUM( "IS_vwSalesbyProductLineComp"."sls_amt"))*100 
	   FROM "100"."dbo"."IS_vwSalesbyProductLineComp"
   where Year = 2021
   and Month between 1 and 12 Group by Mainslspsn_name,PCSummarized),0) AS G2YTD,
		SUM("IS_vwSalesbyProductLineComp"."qty_to_ship"-"IS_vwSalesbyProductLineComp"."qty_return_to_stk") 
		AS Qty_Sold,
   		SUM("IS_vwSalesbyProductLineComp"."sls_amt") 
		AS MTD_Sales,
      	SUM("IS_vwSalesbyProductLineComp"."cost_amt") 
		AS MTD_COGS   
   FROM "100"."dbo"."IS_vwSalesbyProductLineComp"
   where Year = 2021
   and Month = 12
   Group by Mainslspsn_name,PCSummarized
   order by PCSummarized

Código 2

SET ARITHABORT OFF
SET ANSI_WARNINGS OFF
WITH 
T1 AS
(
SELECT (
       SELECT((SUM(IS_vwSalesbyProductLineComp.sls_amt) - SUM(IS_vwSalesbyProductLineComp.cost_amt)) / SUM(IS_vwSalesbyProductLineComp.sls_amt)) * 100) AS G1MTD, 
       IS_vwSalesbyProductLineComp.Mainslspsn_name, 
       IS_vwSalesbyProductLineComp.PCSummarized, 
       (
       SELECT SUM(IS_vwSalesbyProductLineComp.qty_to_ship - IS_vwSalesbyProductLineComp.qty_return_to_stk)
       FROM "100".dbo.IS_vwSalesbyProductLineComp
       WHERE Year = 2021
             AND Month BETWEEN 1 AND 12
       GROUP BY Mainslspsn_name, 
                PCSummarized) AS Qty_Sold, 
       (
       SELECT SUM(IS_vwSalesbyProductLineComp.sls_amt)
       FROM "100".dbo.IS_vwSalesbyProductLineComp
       WHERE Year = 2021
             AND Month BETWEEN 1 AND 12
       GROUP BY Mainslspsn_name, 
                PCSummarized) AS YTD_Sales, 
      (
       SELECT SUM(IS_vwSalesbyProductLineComp.cost_amt)
       FROM "100".dbo.IS_vwSalesbyProductLineComp
       WHERE Year = 2021
             AND Month BETWEEN 1 AND 12
       GROUP BY Mainslspsn_name, 
                PCSummarized) AS YTD_COGS, 
       (
       SELECT((SUM(IS_vwSalesbyProductLineComp.sls_amt) - SUM(IS_vwSalesbyProductLineComp.cost_amt)) / SUM(IS_vwSalesbyProductLineComp.sls_amt)) * 100
       FROM "100".dbo.IS_vwSalesbyProductLineComp
       WHERE Year = 2021
             AND Month BETWEEN 1 AND 12
       GROUP BY Mainslspsn_name, 
                PCSummarized) AS G2YTD, 
       SUM(IS_vwSalesbyProductLineComp.qty_to_ship - IS_vwSalesbyProductLineComp.qty_return_to_stk) AS Qty_Sold2, --> renamed because ambigous
       SUM(IS_vwSalesbyProductLineComp.sls_amt) AS MTD_Sales, 
       SUM(IS_vwSalesbyProductLineComp.cost_amt) AS MTD_COGS
FROM "100".dbo.IS_vwSalesbyProductLineComp
WHERE Year = 2021
      AND Month = 12
GROUP BY Mainslspsn_name, 
         PCSummarized
),
T2 AS 
(
SELECT 0 AS C1, '' AS C2, '' AS C3, 0 AS C4, 0 AS C5, 0 AS C6, 0 AS C7, 0 AS C8, 0 AS C9, 0 AS C10
),
T3 AS
(
SELECT * FROM T1
UNION 
SELECT * FROM T2
)
SELECT SUM(G1MTD) AS G1MTD, 
   (SELECT [text()] = Mainslspsn_name
       FROM "100".dbo.IS_vwSalesbyProductLineComp 
       FOR XML 
           PATH(''),
           TYPE
   ).value
     (
         './text()[1]', 
         'nvarchar(max)'
     ),
   (SELECT [text()] = PCSummarized
       FROM "100".dbo.IS_vwSalesbyProductLineComp 
       FOR XML 
           PATH(''),
           TYPE
   ).value
     (
         './text()[1]', 
         'nvarchar(max)'
     ),
       SUM(Qty_Sold) AS Qty_Sold,
       SUM(YTD_Sales) AS YTD_Sales,
       SUM(YTD_COGS) AS YTD_COGS,
       SUM(G2YTD) AS G2YTD,
       SUM(Qty_Sold2) AS Qty_Sold2,
       SUM(MTD_Sales) AS MTD_Sales,
       SUM(MTD_COGS) AS MTD_COGS
FROM T3
GROUP BY Mainslspsn_name, 
         PCSummarized
ORDER BY PCSummarized;

Solución 1

A falta de datos de muestra, comience abordando estos puntos.

— 100.dbo.IS_vwSalesbyProductLineComp no es un identificador SQL válido. Los identificadores SQL deben comenzar con una letra o un guión bajo.

— no es necesario calificar el nombre de la tabla en columnas si solo selecciona de una tabla

— si va a calificar las columnas, utilice alias en lugar del nombre completo de la tabla para que el script sea más legible, por ejemplo, en lugar de

SQL
select IS_vwSalesbyProductLineComp.sls_amt
from IS_vwSalesbyProductLineComp

usar

SQL
select splc.sls_amt 
from IS_vwSalesbyProductLineComp splc

— elimine los delimitadores en los nombres de columnas y tablas; no son necesarios y solo hacen que su consulta sea ilegible

– Si utiliza delimitadores, utilice [ ] es decir, en lugar de "IS_vwSalesbyProductLineComp" usar [IS_vwSalesbyProductLineComp] – nuevamente, es más legible

— tu declaración

Cita:

pero para la precisión de los datos necesito combinarlos en una sola declaración SQL

no es válido. El número de sentencias SQL utilizadas no influye en absoluto en la precisión de los datos. Obsesionarse con reunir todo en una sola declaración puede ser perjudicial para la claridad, la precisión (del guión, no de los datos) y el rendimiento.

— no hay absolutamente ninguna necesidad de realizar todas esas subconsultas; además, como ha visto, obtendrá varias filas de vuelta

Obtenga todos los datos que necesita en filas separadas; si insiste en que sea una única declaración SQL, utilice una expresión de tabla común (CTE). CON common_table_expression (Transact-SQL) – SQL Server | Documentos de Microsoft[^] ).

Entonces PIVOTE esos resultados para obtener la tabla que desea – consulte Operador PIVOT de SQL Server explicado claramente mediante ejemplos prácticos[^]

Solución 2

A primera vista… tu consulta es realmente mala:
El error más importante es: demasiados SELECT!
Tienes 1 principal SELECT y luego 4 sub-SELECT!

Intente reescribir su consulta para poder utilizar menos cantidad de SELECT.
Consulte cada subconsulta. Si alguno devuelve más de un registro, debe mejorar esa consulta.

Mientras tanto lee esto: Se corrigió el mensaje 512 “La subconsulta devolvió más de 1 valor” en SQL Server[^]

Solución 5

https://www.google.com/search?q=standale+to+Hometown+Agua+Fuego+Restauración
Gran publicación, sin embargo, me preguntaba si podrías escribir un poco más sobre este tema.
Estaría muy agradecido si pudieras explicar un poco más.

¡Salud!

コメント

タイトルとURLをコピーしました