SQL Server Any other method instead of using subquery in select list

zdwk9cvp  于 2023-10-15  发布在  其他
关注(0)|答案(1)|浏览(87)

I have two tables document_header and document_allocation :

CREATE TABLE document_header 
(
    id int, 
    originalAmount decimal(5, 2), 
    doc_type char(2)
)

INSERT INTO document_header(id, originalAmount, doc_type) 
VALUES (1001, '200.00', 'PV'),
       (1002, '150.00', 'PV'),
       (1003, '300.00', 'IV'),
       (1004, '400.00', 'IV'),
       (1005, '600.00', 'IV')

CREATE TABLE document_allocation 
(
    id int, 
    allocatedto int, 
    allocatedfrom int, 
    allocatedamount decimal(5, 2)
)

INSERT INTO document_allocation 
VALUES (1, 1003, 1001, '100.00'),
       (2, 1004, 1001, '50.00'),
       (3, 1003, 1002, '50.00'),
       (4, 1005, 1001, '50.00'),
       (5, 1004, 1002, '50.00'),
       (6, 1003, 1001, '20.00')

I want to get the original document amount also the amount allocated.

Expected result:
| originalDocumentId | documentOriginalAmount | allocatedBy | allocatedamount |
| ------------ | ------------ | ------------ | ------------ |
| 1003 | 300.00 | 1001 | 120.00 |
| 1003 | 300.00 | 1002 | 50.00 |
| 1004 | 400.00 | 1001 | 50.00 |
| 1004 | 400.00 | 1002 | 50.00 |
| 1005 | 600.00 | 1001 | 30.00 |

SQL that returns the result as expected

SELECT
    originalDocument.id AS OriginalDocumentID,
    document_header.id AS allocatedBy,
    (SELECT SUM(document_header_a.originalAmount) 
     FROM document_header document_header_a 
     WHERE document_header_a.id = originalDocument.id),
    SUM(document_allocation.allocatedamount) AS amountAllocated
FROM
    document_header,
    document_allocation,
    document_header originalDocument
WHERE
    document_header.id = document_allocation.allocatedfrom AND
    originalDocument.id = document_allocation.allocatedto
GROUP BY
    originalDocument.id,
    document_header.id

But I don't want to use subquery in the select list, is there any other method?

I tried as below, but it double up the amount

SELECT
    originalDocument.id AS OriginalDocumentID,
    document_header.id AS allocatedBy,
    SUM(originalDocument.originalAmount) AS documentOriginalAmount,
    SUM(document_allocation.allocatedamount) AS amountAllocated
FROM
    document_header,
    document_allocation,
    document_header originalDocument
WHERE
    document_header.id = document_allocation.allocatedfrom AND
    originalDocument.id = document_allocation.allocatedto
GROUP BY
    originalDocument.id,
    document_header.id

Result of this SQL

OriginalDocumentIDdocumentOriginalAmountallocatedByamountAllocated
1003600.001001120.00
1003300.00100250.00
1004400.00100150.00
1004400.00100250.00
1005600.00100130.00

Is there any other method that I can write my SQL so that I can skip using subquery?

mcvgt66p

mcvgt66p1#

I think this will work

;WITH CTE AS 
(
  Select allocatedTo, allocatedFrom, Sum(allocatedamount) amountAllocated
  from document_allocation Group by AllocatedTo, allocatedFrom 
)
Select c.allocatedto as originalDocumentId
  , c.allocatedfrom as allocatedBy
  , H.originalAmount
  , C.amountallocated
from cte as c
inner join document_header H on H.id = c.allocatedto

Here is the Fiddle for you.

Explanation: With CTE you will not have to use any subquery as CTE can handle that part and is also easy to use in place of subquery. Join or subquery in from can also be used but it will defeat the purpose.

相关问题