Làm cách nào để tạo một truy vấn SQL để có các giá trị MTD và YTD trong cùng một hàng?

lập trình


Tôi hiện có một Crystal Report mà tôi đang chuyển đổi sang SSRS. Báo cáo này có 3 cột cho MTD (giá trị từ đầu tháng đến ngày) và 3 cột cho YTD (giá trị từ đầu năm). Tôi có thể tách riêng 3 cột đó nhưng để đảm bảo độ chính xác của dữ liệu, tôi cần kết hợp nó trong một câu lệnh SQL để xuất thành một hàng. Tôi đã có thể làm cho nó gần giống như vậy bằng cách sử dụng một số hàm hợp nhất trong SQL. Vấn đề là nó không cho phép tôi sử dụng nhóm theo lệnh và gây ra lỗi cho tôi. Tôi nên chỉnh sửa gì trong truy vấn SQL của mình theo cách hiển thị trong Báo cáo Crystal bên dưới?
Lỗi :

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.

Báo cáo Crystal hiện tại mà tôi đang chuyển đổi thành SSRS

EDIT: Tôi vừa tạo một mẫu dbfiddle: DB Fiddle – Sân chơi cơ sở dữ liệu SQL[^]

Trong Mã 2, tôi đã thử sử dụng một số with và Union nhưng nó gây ra một số lỗi như

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.

Những gì tôi đã thử:

Mã 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

Mã 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;

Giải pháp 1

Trong trường hợp không có bất kỳ dữ liệu mẫu nào, hãy bắt đầu bằng cách giải quyết những điểm này.

— 100.dbo.IS_vwSalesbyProductLineComp không phải là mã định danh SQL hợp lệ. Mã định danh SQL phải bắt đầu bằng một chữ cái hoặc dấu gạch dưới

— bạn không cần phải xác định tên bảng theo cột nếu chỉ chọn từ một bảng

— nếu bạn định đánh giá các cột thì hãy sử dụng bí danh thay vì tên bảng đầy đủ để làm cho tập lệnh dễ đọc hơn, ví dụ thay vì

SQL
select IS_vwSalesbyProductLineComp.sls_amt
from IS_vwSalesbyProductLineComp

sử dụng

SQL
select splc.sls_amt 
from IS_vwSalesbyProductLineComp splc

— loại bỏ các dấu phân cách trên tên cột và bảng – chúng không cần thiết và chỉ làm cho truy vấn của bạn không thể đọc được

— Nếu bạn sử dụng dấu phân cách thì hãy sử dụng [ ] tức là thay vì "IS_vwSalesbyProductLineComp" sử dụng [IS_vwSalesbyProductLineComp] – một lần nữa, nó dễ đọc hơn

— tuyên bố của bạn

Trích dẫn:

nhưng để đảm bảo độ chính xác của dữ liệu, tôi cần kết hợp nó trong một câu lệnh SQL

không hợp lệ. Số lượng câu lệnh SQL được sử dụng không ảnh hưởng gì đến độ chính xác của dữ liệu. Việc ám ảnh với việc đưa mọi thứ vào một câu lệnh có thể gây bất lợi cho sự rõ ràng, chính xác (của tập lệnh của bạn chứ không phải dữ liệu) và hiệu suất.

— hoàn toàn không cần tất cả các truy vấn phụ đó – hơn nữa, như bạn đã thấy, bạn sẽ nhận được nhiều hàng trở lại

Nhận tất cả dữ liệu bạn cần trong các hàng riêng biệt – nếu bạn nhấn mạnh vào đó là một câu lệnh SQL thì hãy sử dụng Biểu thức bảng chung (CTE – VỚI biểu thức common_table_(Transact-SQL) – Máy chủ SQL | Tài liệu Microsoft[^] ).

Sau đó TRỤC những kết quả đó để có được bảng bạn muốn – xem Toán tử PIVOT của SQL Server được giải thích rõ ràng bằng các ví dụ thực tế[^]

Giải pháp 2

Thoạt nhìn… truy vấn của bạn thực sự tệ:
Sai lầm quan trọng nhất là: quá nhiều CHỌN!
Bạn đã có 1 cái chính SELECT và sau đó là 4 phụSELECT!

Cố gắng viết lại truy vấn của bạn để có thể sử dụng ít hơn SELECT.
Kiểm tra từng truy vấn phụ. Nếu bất kỳ bản ghi nào trả về nhiều bản ghi, bạn phải cải thiện truy vấn đó.

Trong lúc chờ đợi xin vui lòng đọc bài viết này: Sửa lỗi Msg 512 “Truy vấn con trả về nhiều hơn 1 giá trị” trong SQL Server[^]

Giải pháp 5

https://www.google.com/search?q=standale+to+Hometown+Water+Fire+Restoration
Tuy nhiên, bài viết rất hay, tôi tự hỏi liệu bạn có thể viết thêm một chút về chủ đề này không?
Tôi sẽ rất biết ơn nếu bạn có thể giải thích thêm một chút.

Chúc mừng!

コメント

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