Access
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Access

Báo cáo Chi tiết hơn Thông thường - Microsoft Access

Báo cáo Chi tiết hơn Thông thường - Microsoft Access

Thông thường, khi chúng tôi thực hiện báo cáo, chúng tôi thường làm ở mức độ chi tiết cao hơn. Ví dụ:khách hàng thường muốn có một báo cáo hàng tháng về doanh số bán hàng. Cơ sở dữ liệu sẽ lưu trữ doanh số bán hàng riêng lẻ dưới dạng một bản ghi duy nhất, vì vậy không có vấn đề gì khi tổng hợp các số liệu cho từng tháng. Ditto theo năm, hoặc thậm chí chuyển từ danh mục phụ sang danh mục.

Nhưng giả sử họ cần đi xuống ? Nhiều khả năng, câu trả lời sẽ là “thiết kế cơ sở dữ liệu không tốt. phế liệu và bắt đầu lại! ” Rốt cuộc, việc có được độ chi tiết phù hợp cho dữ liệu của bạn là điều cần thiết đối với một cơ sở dữ liệu vững chắc. Nhưng đây không phải là trường hợp quá trình chuẩn hóa không được thực hiện. Hãy xem xét sự cần thiết phải tính toán khoảng không quảng cáo và doanh thu, và xử lý chúng theo cách FIFO. Tôi sẽ nhanh chóng bước sang một bên để chỉ ra rằng tôi không phải là CBA, và bất kỳ khiếu nại kế toán nào mà tôi đưa ra đều phải được xử lý hết sức nghi ngờ. Khi nghi ngờ, hãy gọi cho kế toán của bạn.

Không có tuyên bố từ chối trách nhiệm, hãy xem cách chúng tôi hiện đang lưu trữ dữ liệu. Trong ví dụ này, chúng ta cần ghi lại các giao dịch mua sản phẩm và sau đó chúng ta phải ghi lại các giao dịch mua mà chúng ta vừa mua.

Giả sử rằng đối với một sản phẩm duy nhất, chúng ta có 3 lần mua:
Date | Qty | Per-Cost
9/03 | 3 | $45
9/08 | 6 | $40
9/09 | 8 | $50
Sau đó, chúng tôi sẽ bán những sản phẩm đó vào những dịp khác nhau với giá khác nhau:
Date | Qty | Per-Price
9/05 | 2 | $60
9/07 | 1 | $55
9/10 | 4 | $50
9/12 | 3 | $60
9/15 | 3 | $65
9/19 | 4 | $55

Lưu ý rằng mức độ chi tiết là ở cấp độ giao dịch - chúng tôi tạo một bản ghi duy nhất cho mỗi lần mua hàng và cho mỗi đơn đặt hàng. Điều này rất phổ biến và có ý nghĩa logic - chúng tôi chỉ cần nhập số lượng sản phẩm chúng tôi đã bán, với một mức giá cụ thể cho một giao dịch cụ thể.

OK, nội dung kế toán bạn đã từ chối ở đâu?

Đối với các báo cáo, chúng tôi phải tính toán doanh thu chúng tôi thực hiện trên mỗi đơn vị sản phẩm. Họ nói với tôi rằng họ phải xử lý sản phẩm theo cách FIFO… nghĩa là đơn vị sản phẩm đầu tiên được mua phải là đơn vị sản phẩm đầu tiên được đặt hàng. Sau đó, để tính toán lợi nhuận mà chúng tôi đã thực hiện trên đơn vị sản phẩm đó, chúng tôi phải tra cứu chi phí của đơn vị sản phẩm cụ thể đó, sau đó trừ vào giá đơn vị sản phẩm đó đã được đặt hàng.

Tỷ suất lợi nhuận gộp =doanh thu của sản phẩm - giá thành sản phẩm

Không có gì rung chuyển trái đất, nhưng hãy chờ đợi, hãy nhìn vào các giao dịch mua và đơn đặt hàng! Chúng tôi chỉ có 3 lần mua hàng, với 3 mức chi phí khác nhau, sau đó chúng tôi có 6 đơn hàng với 3 mức giá khác nhau. Sau đó, điểm chi phí sẽ đi đến điểm giá nào?

Công thức tính tỷ suất lợi nhuận gộp đơn giản này, theo cách FIFO giờ đây yêu cầu chúng ta đi đến mức độ chi tiết của từng đơn vị sản phẩm. Chúng tôi không có bất kỳ nơi nào trong cơ sở dữ liệu của mình. Tôi tưởng tượng rằng nếu tôi đề xuất rằng người dùng nhập một bản ghi cho mỗi đơn vị sản phẩm, thì sẽ có một cuộc phản đối khá lớn và có thể là một số tên gọi. Vì vậy, phải làm gì?

Chia tay

Giả sử rằng đối với mục đích kế toán, chúng tôi sẽ sử dụng ngày mua để phân loại từng đơn vị sản phẩm riêng lẻ. Đây là cách nó sẽ xuất hiện:
Line # | Purch Date | Order Date | Per-Cost | Per-Price
1 | 9/03 | 9/05 | $45 | $60
2 | 9/03 | 9/05 | $45 | $60
3 | 9/03 | 9/07 | $45 | $55
4 | 9/08 | 9/10 | $40 | $50
5 | 9/08 | 9/10 | $40 | $50
6 | 9/08 | 9/10 | $40 | $50
7 | 9/08 | 9/10 | $40 | $50
8 | 9/08 | 9/12 | $40 | $60
9 | 9/08 | 9/12 | $40 | $60
10 | 9/09 | 9/12 | $50 | $60
11 | 9/09 | 9/15 | $50 | $65
12 | 9/09 | 9/15 | $50 | $65
13 | 9/09 | 9/15 | $50 | $65
14 | 9/09 | 9/19 | $50 | $55
15 | 9/09 | 9/19 | $50 | $55
16 | 9/09 | 9/19 | $50 | $55
17 | 9/09 | 9/19 | $50 | $55

Nếu bạn nghiên cứu bảng phân tích, bạn có thể thấy rằng có sự trùng lặp trong đó chúng tôi tiêu thụ một số sản phẩm từ một lần mua cho các đơn đặt hàng như vậy trong khi thời gian khác, chúng tôi có một đơn đặt hàng được thực hiện bởi các lần mua khác nhau.

Như đã lưu ý trước đó, chúng tôi thực sự không có 17 hàng đó ở bất kỳ đâu trong cơ sở dữ liệu. Chúng tôi chỉ có 3 hàng mua và 6 hàng đặt hàng. Làm cách nào để chúng ta có được 17 hàng trong số một trong hai bảng?

Đổ thêm bùn

Nhưng chúng tôi chưa làm xong. Tôi vừa cung cấp cho bạn một ví dụ lý tưởng trong đó chúng tôi tình cờ có một số dư hoàn hảo của 17 đơn vị đã mua được đối chiếu với 17 đơn vị đặt hàng cho cùng một sản phẩm. Trong cuộc sống thực, nó không đẹp như vậy. Đôi khi chúng tôi bị bỏ lại với các sản phẩm dư thừa. Tùy thuộc vào mô hình kinh doanh, cũng có thể có nhiều đơn đặt hàng hơn những gì hiện có trong kho. Những thị trường chứng khoán đang chơi này nhận ra chẳng hạn như bán khống.

Khả năng mất cân bằng cũng là lý do tại sao chúng ta không thể thực hiện một cách đơn giản là tổng hợp tất cả các chi phí và giá cả, sau đó trừ đi để có được lợi nhuận. Nếu chúng ta còn lại X đơn vị, chúng ta cần biết chúng là điểm chi phí nào để tính toán hàng tồn kho. Tương tự, chúng ta không thể giả định rằng một đơn hàng chưa được thực hiện sẽ được hoàn thành gọn gàng chỉ bằng một lần mua hàng với một điểm chi phí. Vì vậy, các phép tính chúng tôi thực hiện không chỉ phải hoạt động cho ví dụ lý tưởng mà còn cho trường hợp chúng tôi có hàng tồn kho dư thừa hoặc các đơn đặt hàng chưa được thực hiện.

Đầu tiên chúng ta hãy giải quyết vấn đề tìm ra bao nhiêu loại sản phẩm mà chúng ta cần xem xét. Rõ ràng là SUM () đơn giản của số lượng đơn vị đã đặt hàng hoặc số lượng đơn vị đã mua sẽ không đủ. Không, đúng hơn, chúng ta phải SUM () cả số lượng sản phẩm đã mua và số lượng sản phẩm đã đặt hàng. Sau đó, chúng tôi sẽ so sánh các SUM () và chọn giá trị cao hơn. Chúng ta có thể bắt đầu với truy vấn này:
WITH ProductPurchaseCount AS (
SELECT
p.ProductID,
SUM(p.QtyBought) AS TotalPurchases
FROM dbo.tblProductPurchase AS p
GROUP BY p.ProductID
), ProductOrderCount AS (
SELECT
o.ProductID,
SUM(o.QtySold) AS TotalOrders
FROM dbo.tblProductOrder AS o
GROUP BY o.ProductID
)
SELECT
p.ProductID,
IIF(ISNULL(pc.TotalPurchases, 0) > ISNULL(oc.TotalOrders, 0), pc.TotalPurchases, oc.TotalOrders) AS ProductTransactionCount
FROM dbo.tblProduct AS p
LEFT JOIN ProductPurchaseCount AS pc
ON p.ProductID = pc.ProductID
LEFT JOIN ProductOrderCount AS oc
ON p.ProductID = oc.ProductID
WHERE NOT (pc.TotalPurchases IS NULL AND oc.TotalOrders IS NULL);

Những gì chúng tôi đang làm ở đây là chúng tôi chia thành 3 bước hợp lý:

a) lấy SUM () của số lượng sản phẩm đã mua
b) lấy SUM () của số lượng sản phẩm đặt hàng

Bởi vì chúng tôi không biết liệu chúng tôi có thể có một sản phẩm có thể có một số người mua nhưng không có đơn đặt hàng hoặc một sản phẩm đã đặt hàng nhưng chúng tôi chưa mua, chúng tôi không thể bỏ tham gia cả hai bảng. Vì lý do đó, chúng tôi sử dụng bảng sản phẩm làm nguồn có thẩm quyền của tất cả ProductID mà chúng tôi muốn biết, điều này đưa chúng tôi đến bước thứ 3:

c) đối sánh tổng số tiền với sản phẩm của họ, xác định xem sản phẩm có bất kỳ giao dịch nào không (ví dụ:mua hàng hoặc đơn đặt hàng đã từng được thực hiện) và nếu có, hãy chọn số lượng cao hơn của cặp. Đó là số lượng của chúng tôi về tổng số giao dịch mà một sản phẩm đã có.

Nhưng tại sao lại tính giao dịch?

Mục tiêu ở đây là tìm ra bao nhiêu hàng chúng ta cần tạo trên mỗi sản phẩm để đại diện đầy đủ cho từng đơn vị sản phẩm riêng lẻ đã tham gia vào một giao dịch mua hoặc một đơn đặt hàng. Hãy nhớ trong ví dụ lý tưởng đầu tiên của chúng tôi, chúng tôi có 3 lần mua hàng và 6 lần đặt hàng, cả hai đều cân bằng với tổng số 17 đơn vị sản phẩm được mua sau đó được đặt hàng. Đối với sản phẩm cụ thể đó, chúng tôi sẽ cần có thể tạo hàng 17 để tạo dữ liệu mà chúng tôi có trong hình trên.

Vậy làm cách nào để chuyển giá trị đơn lẻ của 17 liên tiếp thành 17 hàng? Đó là nơi mà sự kỳ diệu của bảng kiểm đếm đi vào.

Nếu bạn chưa nghe nói về bảng kiểm đếm, bạn nên làm ngay bây giờ. Tôi sẽ để những người khác điền bạn vào chủ đề của bảng kiểm đếm; đây, đây và đây. Có thể nói, đó là một công cụ đáng gờm cần có trong bộ công cụ SQL của bạn.

Giả sử chúng ta sửa lại truy vấn trên để phần cuối cùng bây giờ là CTE có tên là ProductTransactionCount, chúng ta có thể viết truy vấn như vậy:
<the 3 CTEs from previous exampe>
INSERT INTO tblProductTransactionStaging (
ProductID,
TransactionNumber
)
SELECT
c.ProductID,
t.Num AS TransactionNumber
FROM ProductTransactionCount AS c
INNER JOIN dbo.tblTally AS t
ON c.TransactionCount >= t.Num;

Và pesto! Bây giờ chúng ta có bao nhiêu hàng mà chúng ta cần - chính xác - cho mỗi sản phẩm mà chúng ta cần hạch toán. Lưu ý biểu thức trong mệnh đề ON - chúng ta đang thực hiện phép nối tam giác - chúng ta không sử dụng toán tử bình đẳng thông thường vì chúng ta muốn tạo ra 17 hàng từ không khí loãng. Lưu ý rằng điều tương tự cũng có thể đạt được với một mệnh đề CROSS JOIN và WHERE. Thử nghiệm với cả hai để tìm cái nào hoạt động tốt hơn.

Làm cho giao dịch của chúng tôi có giá trị

Vì vậy, chúng tôi có bảng tạm thời của chúng tôi được thiết lập đúng số hàng. Bây giờ, chúng ta cần điền vào bảng dữ liệu về các giao dịch mua và đơn đặt hàng. Như bạn đã thấy trong hình, chúng ta cần có thể sắp xếp các giao dịch mua và đơn đặt hàng theo ngày chúng được mua hoặc đặt hàng tương ứng. Và đó là lý do ROW_NUMBER () và bảng kiểm đếm được giải cứu.
SELECT
p.ProductID,
ROW_NUMBER() OVER (PARTITION BY p.ProductID ORDER BY p.PurchaseDate, p.PurchaseID) AS TransactionNumber,
p.PurchaseDate,
p.CostPer
FROM dbo.tblProductPurchase AS p
INNER JOIN dbo.tblTally AS t
ON p.QtyBought >= t.Num;

Bạn có thể thắc mắc tại sao chúng tôi cần ROW_NUMBER () khi chúng tôi có thể sử dụng cột Số của kiểm đếm. Câu trả lời là nếu có nhiều lần mua, thì Num sẽ chỉ cao bằng số lượng của lần mua đó nhưng chúng ta cần tăng lên 17 - tổng của 3 lần mua riêng biệt là 3, 6 và 8 đơn vị. Do đó, chúng tôi phân vùng theo ProductID trong khi tally’s Num có thể được cho là được phân vùng theo PurchaseID, điều không phải như chúng tôi muốn.

Nếu bạn chạy SQL, bây giờ bạn sẽ nhận được một đột phá tuyệt vời, một hàng được trả lại cho mỗi đơn vị sản phẩm đã mua, được đặt hàng theo ngày mua. Lưu ý rằng chúng tôi cũng sắp xếp theo PurchaseID, để xử lý trường hợp có nhiều lần mua cùng một sản phẩm trong cùng một ngày, vì vậy chúng tôi phải phá vỡ ràng buộc bằng cách nào đó để đảm bảo rằng số liệu Mỗi chi phí được tính toán nhất quán. Sau đó, chúng tôi có thể cập nhật bảng tạm thời với giao dịch mua:
WITH PurchaseData AS (
<previous query>
)
MERGE INTO dbo.tblProductTransactionStaging AS t
USING PurchaseData AS p
ON t.ProductID = p.ProductID
AND t.TransactionNumber = p.TransactionNumber
WHEN MATCHED THEN UPDATE SET
t.PurchaseID = p.PurchaseID,
t.PurchaseDate = p.PurchaseDate,
t.CostPer = p.CostPer;

Phần đơn đặt hàng về cơ bản giống nhau - chỉ cần thay thế “Mua hàng” bằng “Đơn đặt hàng” và bạn sẽ nhận được bảng đầy đủ giống như chúng ta đã có trong hình ban đầu ở đầu bài đăng.

Và tại thời điểm này, bạn đã sẵn sàng để thực hiện tất cả các loại kế toán tốt khác vì bây giờ bạn đã chia nhỏ các sản phẩm từ cấp độ giao dịch xuống cấp độ đơn vị mà bạn cần lập bản đồ chính xác chi phí hàng hóa với doanh thu. cho đơn vị sản phẩm cụ thể đó sử dụng FIFO hoặc LIFO theo yêu cầu của kế toán viên của bạn. Các phép tính hiện là sơ cấp.

Mức độ chi tiết trong thế giới OLTP

Khái niệm về mức độ chi tiết là một khái niệm phổ biến hơn trong kho dữ liệu so với các ứng dụng OLTP nhưng tôi nghĩ kịch bản được thảo luận nêu bật sự cần thiết phải lùi lại và xác định rõ ràng mức độ chi tiết hiện tại của lược đồ OLTP. Như chúng tôi đã thấy, chúng tôi đã có sai chi tiết ban đầu và chúng tôi cần phải làm việc lại để chúng tôi có thể có được mức độ chi tiết cần thiết để đạt được báo cáo của chúng tôi. Thật là một tai nạn đáng mừng là trong trường hợp này, chúng tôi có thể hạ thấp chính xác mức độ chi tiết vì chúng tôi đã có tất cả dữ liệu thành phần nên chúng tôi chỉ cần chuyển đổi dữ liệu. Điều đó không phải luôn luôn như vậy và có nhiều khả năng là nếu lược đồ không đủ chi tiết, nó sẽ đảm bảo việc thiết kế lại lược đồ. Tuy nhiên, việc xác định mức độ chi tiết cần thiết để đáp ứng các yêu cầu giúp xác định rõ ràng các bước hợp lý mà bạn phải thực hiện để đạt được mục tiêu đó.

Tập lệnh SQL hoàn chỉnh để chứng minh quan điểm có thể nhận được DemoLowGranularity.sql.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Gỡ lỗi các thủ tục riêng tư

  2. Cách tạo bảng ở dạng xem biểu dữ liệu trong Access 2016

  3. “Bình thường hóa” Cơ sở dữ liệu có nghĩa là gì?

  4. 4 cách để bảo vệ thông tin nhạy cảm khỏi khách hàng của bạn

  5. Làm thế nào để hiện đại hóa doanh nghiệp của bạn vào năm 2022