Get payment total minus amount received - sql-server

I have two tables.
1.Invoice
invoice_Id invoice_no client_id date total_price
-----------------------------------------------------------------------------
2 INV00001 9 2014-10-15 200.00
7 INV00002 9 2014-10-16 560.00
8 INV00003 9 2014-10-21 100.00
11 INV00004 9 2014-10-27 101.00
2.Invoice_payment
InvPayment_id client_id Invoice_Id receipt_no payment_date amount_received discount
--------------------------------------------------------------------------------------------
6 9 8 REC00002 2014-10-31 5.00 0.00
Now I want to get Total Amount Due by Client by totalling the invoice amounts and subtracting any amounts received.
Expected Result:
client_id Total_price Due_Amount
-----------------------------------------------------------------------------
9 961.00 956.00
NOTES:
There will be zero rows if no payments are taken to date.
There could be multiple rows if more than one payment is taken.
Here is what I have tried:
;WITH cte (clientid, invoiceid, paid, disc)
As
(
Select client_id clientId, invoice_Id invoiceId, sum(amount_received) paid, sum(discount) disc
From tbl_Invoice_Payment
Group by invoice_id, client_id
)
Select I.client_id, invoice_Id, invoice_no, I.due_date
,SUM(I.total_price), Isnull(SUM(paid), 0) Paid, (SUM(Total_price) - Isnull(SUM(paid),0) - Isnull(SUM(disc),0)) Balance
--,I.total_price, Isnull(paid, 0) Paid, (Total_price - Isnull(paid,0) - Isnull(disc,0)) Balance
From tbl_invoice I Left join cte On I.client_id = cte.clientId
And I.invoice_id = cte.invoiceid
left join tbl_client C on C.client_id = I.client_id
group by I.client_id, invoice_Id, invoice_no, due_date, account_type, company_name, total_price, paid, disc
order by company_name
But it's not working as intended.

Instead of using a CTE, you can simply add a subquery to return the result of payments made and subtract that value from the total:
SQL Fiddle Demo
Schema Setup:
CREATE TABLE Invoice
([invoice_Id] int, [invoice_no] varchar(8), [client_id] int,
[date] datetime, [total_price] decimal(5,2));
INSERT INTO Invoice
([invoice_Id], [invoice_no], [client_id], [date], [total_price])
VALUES
(2, 'INV00001', 9, '2014-10-15 00:00:00', 200.00),
(7, 'INV00002', 9, '2014-10-16 00:00:00', 560.00),
(8, 'INV00003', 9, '2014-10-21 00:00:00', 100.00),
(11, 'INV00004', 9, '2014-10-27 00:00:00', 101.00);
CREATE TABLE Invoice_Payment
([InvPayment_id] int, [client_id] int, [Invoice_Id] int, [receipt_no] varchar(8),
[payment_date] datetime, [amount_received] decimal(5,2), [discount] int);
INSERT INTO Invoice_Payment
([InvPayment_id], [client_id], [Invoice_Id], [receipt_no], [payment_date],
[amount_received], [discount])
VALUES
(6, 9, 8, 'REC00002', '2014-10-31 00:00:00', 5.00, 0.00);
Query to generate output::
SELECT i.client_id , SUM(i.total_price) AS Total_price,
SUM(i.total_price) - ( SELECT SUM(ip.amount_received)
FROM dbo.Invoice_Payment ip
WHERE i.client_id = ip.client_id
) AS DueAmount
FROM dbo.Invoice i
WHERE client_id = 9
GROUP BY client_id
Results:
| CLIENT_ID | TOTAL_PRICE | DUEAMOUNT |
|-----------|-------------|-----------|
| 9 | 961 | 956 |

Please select the values you want. The problem is related to grouping.
In the group by clause I.client_id, invoice_Id, invoice_no, due_date, account_type, company_name, total_price, paid, disc this much fields are specified. invoice_Id, invoice_no prevent grouping which you need. Remove both invoice_Id and invoice_no from select and group by and try again.

Related

Total Number of Leaves of same type in a month

I have 2 tables name EmployeeInfo and Leave and I am storing the values that which employee have taken which type of leave in month and how many times.
I am trying to calculate the number of leaves of same type but I'm stuck at one point for long time.
IF EXISTS(SELECT 1 FROM sys.tables WHERE object_id = OBJECT_ID('Leave'))
BEGIN;
DROP TABLE [Leave];
END;
GO
IF EXISTS(SELECT 1 FROM sys.tables WHERE object_id = OBJECT_ID('EmployeeInfo'))
BEGIN;
DROP TABLE [EmployeeInfo];
END;
GO
CREATE TABLE [EmployeeInfo] (
[EmpID] INT NOT NULL PRIMARY KEY,
[EmployeeName] VARCHAR(255)
);
CREATE TABLE [Leave] (
[LeaveID] INT NOT NULL PRIMARY KEY,
[LeaveType] VARCHAR(255) NULL,
[DateFrom] VARCHAR(255),
[DateTo] VARCHAR(255),
[Approved] Binary,
[EmpID] INT FOREIGN KEY REFERENCES EmployeeInfo(EmpID)
);
GO
INSERT INTO EmployeeInfo([EmpID], [EmployeeName]) VALUES
(1, 'Marcia'),
(2, 'Lacey'),
(3, 'Fay'),
(4, 'Mohammad'),
(5, 'Mike')
INSERT INTO Leave([LeaveID],[LeaveType],[DateFrom],[DateTo], [Approved], [EmpID]) VALUES
(1, 'Annual Leave','2018-01-08 04:52:03','2018-01-10 20:30:53', 1, 1),
(2, 'Sick Leave','2018-02-10 03:34:41','2018-02-14 04:52:14', 0, 2),
(3, 'Casual Leave','2018-01-04 11:06:18','2018-01-05 04:11:00', 1, 3),
(4, 'Annual Leave','2018-01-17 17:09:34','2018-01-21 14:30:44', 0, 4),
(5, 'Casual Leave','2018-01-09 23:31:16','2018-01-12 15:11:17', 1, 3),
(6, 'Annual Leave','2018-02-16 18:01:03','2018-02-19 17:16:04', 1, 2)
My query which I have tried so far look something like this.
SELECT Info.EmployeeName, Leave.LeaveType, SUM(DATEDIFF(Day, Leave.DateFrom, Leave.DateTo)) [#OfLeaves], DatePart(MONTH, Leave.DateFrom)
FROM EmployeeInfo Info, Leave
WHERE Info.EmpID = Leave.EmpID AND Approved = 1
GROUP BY Info.EmployeeName, Leave.LeaveType, [Leave].[DateFrom], [Leave].[DateTo]
And the record like given below
EmployeeName LeaveType #OfLeaves MonthNumber
-------------- ----------------- ----------- -----------
Fay Casual Leave 1 1
Fay Casual Leave 3 1
Lacey Annual Leave 3 2
Marcia Annual Leave 2 1
I want the record to look like this
EmployeeName LeaveType #OfLeaves MonthNumber
-------------- ----------------- ----------- -----------
Fay Casual Leave 4 1
Lacey Annual Leave 3 2
Marcia Annual Leave 2 1
If you don't want to modify existing query due to some constraint, this might work:
Select iq.EmployeeName, iq.LeaveType, SUM(iq.#OfLeaves) as #OfLeaves, iq.MonthNumber
From (
SELECT Info.EmployeeName, Leave.LeaveType, SUM(DATEDIFF(Day, Leave.DateFrom, Leave.DateTo)) [#OfLeaves], DatePart(MONTH, Leave.DateFrom) as MonthNumber
FROM EmployeeInfo Info, Leave
WHERE Info.EmpID = Leave.EmpID AND Approved = 1
GROUP BY Info.EmployeeName, Leave.LeaveType, [Leave].[DateFrom], [Leave].[DateTo]
)iq
group by iq.EmployeeName, iq.LeaveType, iq.MonthNumber
This just need small adjustment with your query in the GROUP BY clause. Instead of grouping them by [Leave].[DateFrom] and [Leave].[DateTo] which causes the row to be separated, you need to group it with the calculated column that uses datepart.
SELECT Info.EmployeeName,
Leave.LeaveType,
SUM(DATEDIFF(Day, Leave.DateFrom, Leave.DateTo)) [#OfLeaves],
DatePart(MONTH, Leave.DateFrom)
FROM EmployeeInfo Info
INNER JOIN Leave
ON Info.EmpID = Leave.EmpID
WHERE Approved = 1
GROUP BY Info.EmployeeName,
Leave.LeaveType,
DatePart(MONTH, Leave.DateFrom) -- <<<< change only this part
Here's a Demo.
I have also modified the syntax into ANSI format.

Getting Running Total of Time column using T-SQL in SQL server

I have a table XYZ with employee login duration details in TIME datatype column.
EmployeeID | DomainID | LoginDuration
----------------------------------------------------------------
1111 12 02:32:55:0000000
1111 4 00:57:17.0000000
1111 12 01:06:25.0000000
1111 11 03:31:23.0000000
2222 11 02:42:17.0000000
2222 4 03:54:52.0000000
2222 10 04:08:29.0000000
Apart from the above columns, I also have LoginTimeStamp and LoginWeek columns, which I am using in a JOIN statement.
I am trying to obtain running totals for the LoginDuration Column as follows:
EmployeeID | DomainID | HoursBefore | LoginDuration | HoursAfter |
---------------------------------------------------------------------------------
1111 12 00:00:00.0000000 02:32:55:0000000 **00:00:00.0000000**
1111 4 02:32:55.0000000 00:57:17.0000000 03:30:12.0000000
1111 12 03:30:12.0000000 01:06:25.0000000 04:36:37.0000000
1111 11 04:36:37.0000000 03:31:23.0000000 08:08:00.0000000
2222 11 00:00:00.0000000 02:42:17.0000000 **00:00:00.0000000**
2222 4 01:32:31.0000000 03:54:52.0000000 04:14:48.0000000
2222 10 04:14:48.0000000 04:08:29.0000000 08:09:40.0000000
HoursBefore is Previous Value of HoursAfter(00:00:00 for first row of each employee)
HoursAfter = HoursBefore+LoginDuration
For this purpose,I wrote the below query, But I am getting an error with the HoursAfter Column. It is not adding up the current value and previous value for each employee.
SELECT
a.EmployeeID,a.LoginDuration,
COALESCE(CAST(
DATEADD(ms,
SUM(DATEDIFF(ms,0,CAST(b.LoginDuration as datetime)))
, 0)
as time)
,'00:00:00') AS HoursBefore,
a.LoginDuration as Hours,
COALESCE(CAST(
DATEADD(ms,
SUM(DATEDIFF(ms,0,CAST(b.LoginDuration as datetime)))
, a.Loginduration)
as time)
,'00:00:00') As HoursAfter
FROM XYZ AS a
LEFT OUTER JOIN XYZ AS b
ON (a.EmployeeID = b.EmployeeID)
AND (a.LoginWeek = b.LoginWeek)
AND (b.LoginTimeStamp < a.LoginTimeStamp)
GROUP BY a.EmployeeID, a.LoginTimeStamp,a.LoginDuration
ORDER BY a.LoginWeek, a.EmployeeID, a.LoginTimeStamp;
I need help with the query such that the HoursAfter column for each employee is appropriate.
Any help would be greatly appreciated.
(This is my first query, reply if you may need any further details.)
Thanks.
Pity SQL Server doesn't support period datatype yet, it would make the math so much simpler.
However, it dos have rather good support for window functions in newer versions, which we can use to solve this:
declare #t table (ID int, EmployeeID int, DomainID int, LoginDuration time)
insert #t
values
(1, 1111, 12, '02:32:55.0000000'),
(2, 1111, 4, '00:57:17.0000000'),
(3, 1111, 12, '01:06:25.0000000'),
(4, 1111, 11, '03:31:23.0000000'),
(5, 2222, 11, '02:42:17.0000000'),
(6, 2222, 4, '03:54:52.0000000'),
(7, 2222, 10, '04:08:29.0000000')
;with x as (
select *, dateadd(second, sum(datediff(second, 0, loginduration)) over (partition by employeeid order by id), 0) sum_duration_sec,
row_number() over (partition by employeeid order by id) rn
from #t
)
select
employeeid,
domainid,
convert(time, isnull(lag(sum_duration_sec) over (partition by employeeid order by id),0)) hoursbefore,
loginduration,
convert(time, case when rn = 1 then 0 else sum_duration_sec end) hoursafter
from x
I introduced the ID column for brevity to establish the sequence, you'd probably want to use the (LoginWeek, LoginTimestamp) to order by.
Also, not sure about the requirement that HoursAfter should be 0 in 1st and 5th row - if not, delete the row_number() thing altogether.
use OUTER APPLY to calculate the Hours After. Hours Before is just Hours After subtracting current duration
SELECT a.EmployeeID, a.DomainID,
HoursBefore = CONVERT(TIME, DATEADD(SECOND, b.after_secs - DATEDIFF(SECOND, 0, a.LoginDuration), 0)),
a.LoginDuration,
HoursAfter = CONVERT(TIME, DATEADD(SECOND, b.after_secs, 0))
FROM XYZ AS a
OUTER APPLY
(
SELECT after_secs = SUM(DATEDIFF(SECOND, 0, x.LoginDuration))
FROM XYZ x
WHERE x.EmployeeID = a.EmployeeID
AND x.LoginWeek = a.LoginWeek
AND x.LoginTimeStamp <= a.LoginTimeStamp
) b

Get Sum of BudgetTransactionLine

I'm trying to get sum of budget transaction line by month .Is there an error on my Query.
The result of my query is :
RECIDLine RecIDHeader Date Amount
5637157326 5637149076 2012-08-01 00:00:00.000 850.00
5637157342 5637149079 2012-12-01 00:00:00.000 1000.00
5637157343 5637149079 2012-12-01 00:00:00.000 80.00
5637157344 5637149079 2012-12-01 00:00:00.000 2700.00
But i want to get somthing like this :
RECIDLine RecIDHeader Date Amount
5637157326 5637149076 2012-08-01 00:00:00.000 850.00
5637157342 5637149079 2012-12-01 00:00:00.000 3780.00
This is my query :
IF OBJECT_ID('tempdb..#BudgetTransTmp') IS NOT NULL
DROP TABLE #BudgetTransTmp
Select
BudgetTransactionLine.RECID AS RecIdLine,
BUDGETTRANSACTIONHEADER.RECID AS RecIdHeader,
BudgetTransactionLine.DATE,
SUM(CAST((BudgetTransactionLine.TransactionCurrencyAmount ) as decimal(18,2))) AS Amount
INTO #BudgetTransTmp
FROM MicrosoftDynamicsAX.dbo.BudgetTransactionLine AS BudgetTransactionLine
INNER JOIN MicrosoftDynamicsAX.dbo.BUDGETTRANSACTIONHEADER AS BUDGETTRANSACTIONHEADER
ON BUDGETTRANSACTIONHEADER.RECID = BudgetTransactionLine.BUDGETTRANSACTIONHEADER
AND BUDGETTRANSACTIONHEADER.budgetTransactionType = '3'
AND BUDGETTRANSACTIONHEADER.PARTITION = #Partition
WHERE BudgetTransactionLine.PARTITION =#Partition
AND BudgetTransactionCode.DATAAREAID = 'USMF'
AND BudgetTransactionLine.DATE >= PeriodCalandarTmp.StartDate
AND BudgetTransactionLine.DATE <= PeriodCalandarTmp.EndDate
GROUP BY BudgetTransactionLine.DATE,
BUDGETTRANSACTIONHEADER.RECID,
BudgetTransactionLine.RECID
select * from #BudgetTransTmp
And I need to keep BudgetTransactionLine.RECID in select
You should not include BudgetTransactionLine.RecId (RecIdLine) in your GROUP BY.
If you need this column, then you must use one of Aggregate Function (for example in the SELECT part MIN(BudgetTransactionLine.RecId) AS RecIdLine.
just put you whole data in Simple CTE and just join with your Temp table. Please go through the query carefully insert your code according to that
Below the Sample data
declare #Table1 TABLE
(RECIDLine BIGint, RecIDHeader BIGint, Date varchar(30), Amount DECIMAL(18,2))
;
INSERT INTO #Table1
(RECIDLine, RecIDHeader, Date, Amount)
VALUES
(5637157326, 5637149076, '2012-08-01 00:00:00.000', 850.00),
(5637157342, 5637149079, '2012-12-01 00:00:00.000', 1000.00),
(5637157343, 5637149079, '2012-12-01 00:00:00.000', 80.00),
(5637157344, 5637149079, '2012-12-01 00:00:00.000', 2700.00)
;
;WITH CTE AS (
select RecIDHeader,Date,SUM(Amount)Amount,ROW_NUMBER()OVER(PARTITION BY RecIDHeader ORDER BY Date)RN from #Table1
GROUP BY RecIDHeader,Date )
Select T.RECIDLine,C.RecIDHeader,C.Amount,C.Amount FROM CTE C
INNER JOIN (select MIN(RECIDLine) RECIDLine, RecIDHeader from #Table1
GROUP BY RecIDHeader)T
ON T.RecIDHeader = C.RecIDHeader

how to insert record in between particular record in SQL

suppose i have a customer balance details table. For Example :
CustID CustName CustDate Amt Bal
1 DP 1/5/2013 1000 1000
1 DP 5/5/2013 100 1100
1 Dhara 10/5/2013 1000 1000
1 DP 10/5/2013 1000 2100
now user insert a record CustName = DP , CustDate = 7/5/2013 , Amt = 400 then that record should be added after date 5/5/2013 and before 10/5/2013 and respective balance should be change also as follows :
CustID CustName CustDate Amt Bal
1 DP 1/5/2013 1000 1000
1 DP 5/5/2013 100 1100
1 DP 7/5/2013 400 1500
1 Dhara 10/5/2013 1000 1000
1 DP 10/5/2013 1000 2500
How do i achieve when inserting record in database ? How do i check when date lies between already inserted records ? Please Help
I think, you can get what you want if you use an ORDER BY clause to access the data in the desired order. Please also refer to your DB documentation for the use of indices.
Here is one suggestion on how do do it: http://www.sqlfiddle.com/#!3/d341b/9
CREATE TABLE Customer
(
CustId INT,
CustName NVARCHAR(150),
CustDate DATE,
Amt INT,
)
INSERT INTO Customer
(CustID, CustName, CustDate, Amt)
VALUES
(1, 'DP', '2013-01-05 00:00:00', 1000),
(1, 'DP', '2013-05-05 00:00:00', 100),
(1, 'DP', '2013-07-05 00:00:00', 400),
(1, 'Dhara', '2013-10-05 00:00:00', 1000),
(1, 'DP', '2013-10-05 00:00:00', 1000)
;
;WITH RankedCustomer AS
(
SELECT
CustId
, CustName
, CustDate
, Amt
, ROW_NUMBER() OVER(ORDER BY CustDate) Row
FROM
Customer
)
SELECT
Customer.CustId
, Customer.CustName
, Customer.CustDate
, Customer.Amt
, SUM(PreviousCustomer.Amt)
FROM
RankedCustomer Customer
LEFT JOIN RankedCustomer PreviousCustomer
ON PreviousCustomer.CustId = Customer.CustId
AND PreviousCustomer.CustName = Customer.CustName
AND PreviousCustomer.Row <= Customer.Row
GROUP BY
Customer.CustId
, Customer.CustName
, Customer.CustDate
, Customer.Amt
ORDER BY
Customer.CustDate

Trouble creating SQL Query to update line item amounts

I'm going to preface this question with the disclaimer that creating what I call "complex" queries isn't in my forte. Most of the time, there is a much simpler way to accomplish what I'm trying to accomplish so if the below query isn't up to par, I apologize.
With that said, I have a table that keeps track of Vendor Invoices and Vendor Invoice Items (along with a Vendor Invoice Type and Vendor Invoice Item Type). Our bookkeeper wants a report that simply shows: Vendor | Location | Inv Number | Inv Type | Item Type | Inv Date | Rental Fee | Restock Fee | Shipping Fee | Line Item Cost | Total (Line Item + Fees)
Most of the time, one vendor invoice is one line. However, there are exceptions where a vendor invoice can have many item types, thus creating two rows. Not a big deal EXCEPT the fees (Rental, Restock, Shipping) are attached to the Vendor Invoice table. So, I first created a query that checks the temp table for Invoices that have multiple rows, takes the last row, and zero's out the fees. So that only one line item would have the fee. However, our bookkeeper doesn't like that. Instead, she'd like the fees to be "distributed" among the line items.
So, if a vendor invoice has a $25 shipping charge, has two line items, then each line item would be $12.50.
After working with the query, I got it to update the Last Row to be the adjusted amount but row 1+ would have the original amount.
I'm going to post my entire query here (again - I'm sorry that this may not be the best looking query; however, suggestions are always welcome)
DROP TABLE #tVendorInvoiceReport
DROP TABLE #tSummary
SELECT v.Name AS Vendor ,
vii.Location ,
vi.VendorInvNumber ,
vit.Descr AS InvoiceType ,
vii.VendorInvoiceItemType ,
CONVERT(VARCHAR(10), vi.VendorInvDate, 120) VendorInvDate ,
vi.RentalFee ,
vi.RestockFee ,
vi.ShippingFee ,
SUM(vii.TotalUnitCost) TotalItemCost ,
CONVERT(MONEY, 0) TotalInvoice ,
RowID = IDENTITY( INT,1,1)
INTO #tVendorInvoiceReport
FROM dbo.vVendorInvoiceItems AS vii
JOIN dbo.VendorInvoices AS vi ON vii.VendorInvID = vi.VendorInvID
JOIN dbo.Vendors AS v ON vi.VendorID = v.VendorID
JOIN dbo.VendorInvoiceTypes AS vit ON vi.VendorInvTypeID = vit.VendorInvTypeID
WHERE vi.VendorInvDate >= '2012-01-01'
AND vi.VendorInvDate <= '2012-01-31'
GROUP BY v.Name ,
vii.Location ,
vi.VendorInvNumber ,
vit.Descr ,
vii.VendorInvoiceItemType ,
CONVERT(VARCHAR(10), vi.VendorInvDate, 120) ,
vi.RentalFee ,
vi.RestockFee ,
vi.ShippingFee
ORDER BY v.Name ,
vii.Location ,
vi.VendorInvNumber ,
vit.Descr ,
vii.VendorInvoiceItemType ,
CONVERT(VARCHAR(10), vi.VendorInvDate, 120)
SELECT VendorInvNumber ,
COUNT(RowID) TotalLines ,
MAX(RowID) LastLine
INTO #tSummary
FROM #tVendorInvoiceReport
GROUP BY VendorInvNumber
WHILE ( SELECT COUNT(LastLine)
FROM #tSummary AS ts
WHERE TotalLines > 1
) > 0
BEGIN
DECLARE #LastLine INT
DECLARE #NumItems INT
SET #LastLine = ( SELECT MAX(LastLine)
FROM #tSummary AS ts
WHERE TotalLines > 1
)
SET #NumItems = ( SELECT COUNT(VendorInvNumber)
FROM #tVendorInvoiceReport
WHERE VendorInvNumber IN (
SELECT VendorInvNumber
FROM #tSummary
WHERE LastLine = #LastLine )
)
UPDATE #tVendorInvoiceReport
SET RentalFee = ( RentalFee / #NumItems ) ,
RestockFee = ( RestockFee / #NumItems ) ,
ShippingFee = ( ShippingFee / #NumItems )
WHERE RowID = #LastLine
DELETE FROM #tSummary
WHERE LastLine = #LastLine
--PRINT #NumItems
END
UPDATE #tVendorInvoiceReport
SET TotalInvoice = ( TotalItemCost + RentalFee + RestockFee + ShippingFee )
SELECT Vendor ,
Location ,
VendorInvNumber ,
InvoiceType ,
VendorInvoiceItemType ,
VendorInvDate ,
RentalFee ,
RestockFee ,
ShippingFee ,
TotalItemCost ,
TotalInvoice
FROM #tVendorInvoiceReport AS tvir
I sincerely appreciate anyone who took the time to read this and attempt to point me in the right direction.
Thank you,
Andrew
PS - I did try and remove "WHERE RowID = #LastLine" from the first Update, but that changed the Shipping Fees for the first line with two items to "0.0868" instead of 12.50 ($25/2)
If I understand correctly, you're looking for a way to split something like an invoice shipping fee over one or more invoice items.
I created some sample invoice and invoice item tables shown below and used the
over(partition) clause to split out the shipping per item.
-- sample tables
declare #Invoice table (InvoiceID int, customerID int, Date datetime, ShippingFee float)
declare #InvoiceItem table (InvoiceItemID int identity, InvoiceID int, ItemDesc varchar(50), Quantity float, ItemPrice float)
-- Example 1
insert #Invoice values(1, 800, getdate(), 20);
insert #InvoiceItem values(1, 'Widget', 1, 10.00)
insert #InvoiceItem values(1, 'Wing Nut', 5, 2.00)
insert #InvoiceItem values(1, 'Doodad', 8, 0.50)
insert #InvoiceItem values(1, 'Thingy', 3, 1.00)
-- Example 2
insert #Invoice values(2, 815, getdate(), 15);
insert #InvoiceItem values(2, 'Green Stuff', 10, 1.00)
insert #InvoiceItem values(2, 'Blue Stuff', 10, 1.60)
-- Example 3
insert #Invoice values(3, 789, getdate(), 15);
insert #InvoiceItem values(3, 'Widget', 10, 1.60)
-- query
select
n.InvoiceID,
n.InvoiceItemID,
n.ItemDesc,
n.Quantity,
n.ItemPrice,
ExtendedPrice = n.Quantity * n.ItemPrice,
Shipping = i.ShippingFee / count(n.InvoiceItemID) over(partition by n.InvoiceID)
from #InvoiceItem n
join #Invoice i on i.InvoiceID = n.InvoiceID
Output:
InvoiceID InvoiceItemID ItemDesc Quantity ItemPrice ExtendedPrice Shipping
1 1 Widget 1 10 10 5
1 2 Wing Nut 5 2 10 5
1 3 Doodad 8 0.5 4 5
1 4 Thingy 3 1 3 5
2 5 Green Stuff 10 1 10 7.5
2 6 Blue Stuff 10 1.6 16 7.5
3 7 Widget 10 1.6 16 15

Resources