SQL Server getting values from 4 tables into ONE - sql-server

I have 5 Tables :
1- UserAccount : Has AccountNumber field
2- Total Amount : Has AccountNumber field
3- Total Withdrawal : Has AccountNumber field
4- Total Profit : Has AccountNumber field
5- Balance : Has AccountNumber field
I need to get the values of [Total Amount], [Total Withdrawal], [Total Profit] & [Balance] for each user in ONE table to be like:
AccountNumber Balance Total Amount Total Withdrawal Total Profit
----------------------------------------------------------------------------------
201 450 600 150 250
222 600 800 200 150
I used this query but the results isn't correct:
SELECT DISTINCT
dbo.useraccount.AccountNumber,
dbo.useraccount.FirstName,
dbo.useraccount.SecondName,
dbo.Balance.Balance,
sum(dbo.[Total Amount].DepositTotal) AS [Total Deposit],
Sum(dbo.[Total Profit].ProfitTotal) AS [Total Profit],
Sum(dbo.[Total Withdrawal].WithdrawalTotal) AS [Total Withdrawal]
FROM
dbo.useraccount ,
dbo.Balance ,
dbo.[Total Amount] ,
dbo.[Total Profit] ,
dbo.[Total Withdrawal]
WHERE
dbo.useraccount.AccountNumber = dbo.Balance.AccountNumber AND
dbo.useraccount.AccountNumber = dbo.[Total Amount].AccountNumber AND
dbo.useraccount.AccountNumber = dbo.[Total Profit].AccountNumber AND
dbo.useraccount.AccountNumber = dbo.[Total Withdrawal].AccountNumber
GROUP BY
dbo.useraccount.AccountNumber,
dbo.useraccount.FirstName,
dbo.useraccount.SecondName,
dbo.Balance.Balance
Any help please?
The results i am getting is something like this:
AccountNumber Balance Total Amount Total Withdrawal Total Profit
-----------------------------------------------------------------------
201 5316.52 291060.00 86328.20 51150.00
220 35000.00 2086400.00 648000.00 532800.00
221 12000.00 192000.00 44548.00 44548.00
222 8500.00 76500.00 12003.75 12003.75
224 4000.00 484000.00 120780.00 120780.00
226 2393.50 48000.00 5206.50 10736.00
When i run this query for [Total Profit] i get correct results:
SELECT DISTINCT
dbo.[Total Profit].AccountNumber,
Sum(dbo.[Total Profit].ProfitTotal) As [Total Deposit]
FROM
dbo.[Total Profit]
GROUP BY
dbo.[Total Profit].AccountNumber

Well, given that you haven't posted your tables definition, you can do this to avoid the duplication of rows:
SELECT UA.AccountNumber,
UA.FirstName,
UA.SecondName,
B.Balance,
TA.DepositTotal [Total Deposit],
TP.ProfitTotal [Total Profit],
TW.WithdrawalTotal [Total Withdrawal]
FROM dbo.useraccount UA
LEFT JOIN ( SELECT AccountNumber, SUM(Balance) Balance
FROM dbo.Balance
GROUP BY AccountNumber) B
ON UA.AccountNumber = B.AccountNumber
LEFT JOIN ( SELECT AccountNumber, SUM(DepositTotal) DepositTotal
FROM dbo.[Total Amount]
GROUP BY AccountNumber) TA
ON UA.AccountNumber = TA.AccountNumber
LEFT JOIN ( SELECT AccountNumber, SUM(ProfitTotal) ProfitTotal
FROM dbo.[Total Profit]
GROUP BY AccountNumber) TP
ON UA.AccountNumber = TP.AccountNumber
LEFT JOIN ( SELECT AccountNumber, SUM(WithdrawalTotal) WithdrawalTotal
FROM dbo.[Total Withdrawal]
GROUP BY AccountNumber) TW
ON UA.AccountNumber = TW.AccountNumber
Of course, you shouldn't need to do that aggregation for every table, only the ones that have multiple rows for each AccountNumber.

Related

How to add and deduct quantity in inventory for SQL Server

I am developing simple inventory system but I am having hard time getting the accurate stock on hand after calculating the 3 quantities from 3 different tables. My goal is to add the sum of receiving_stock + sum of returning_stock - the outgoing_stock. But if outgoing_stock has no data all the records are null.
Here’s my data and query.
receiving_stock
Prod_ID, Qty
123 10
124 10
returning_stock
Prod_ID, Qty
124 10
125 10
outgoing_stock
No Data Yet
Actual Result:
Prod_id, qty
Null 10
Null 20
Null 10
Desired Result:
Prod_id, qty
123 10
124 20
125 10
Query:
Select prod_id, isnull(qty,0)-isnull(sold,0) on-hand
Select prod_id, sum(qty) qty
(
select prod_id,qty
From receiving_stock
Union all
select prod_id,qty
From returning_stock
) Za
Group by prod_id
) Zb
Left join
(
From
Select prod_id, sum(qty) sold
From outgoing_stock
Group by prod_id
) zc
) zd
On
Zb.prod_id=zd.prod_id
You can include the third table in UNION ALL with a negative quantity :
SELECT prod_id,qty
From receiving_stock
UNION ALL
SELECT prod_id,qty
From returning_stock
UNION ALL
SELECT prod_id, -qty
From outgoing_stock

Combine multiple SQL queries into single result

I'm trying to get the result of 2 queries into a single result set. I'm using SQL Server 2019 Express.
Here is the data I'm working with:
Table Sales
SaleDate
SaleAmt
CustomerID
11/1/2021
500
123
11/1/2021
100
234
11/1/2021
300
345
11/2/2021
500
456
11/2/2021
100
567
11/2/2021
200
678
Table Customers
CustomerID
CustomerName
123
Jon Doe
234
Jane Doe
456
Bob Doe
678
Jim Doe
Query #1:
select sales.saledate, sum(sales.saleamt) as 'Total Sales from All'
from Sales
group by sales.saledate
Query #2:
select sales.saledate, sum(sales.saleamt) as 'Total Sales from Customers'
from Sales
where sales.customerid in (select customerid from customers)
group by sales.saledate
This is my desired result:
SaleDate
Total Sales from All
Total Sales from Customers
11/1/2021
900
600
11/2/2021
800
700
you can use join on the date of the sale
select s1.saledate, All_Total AS 'Total Sales from All', CustomersTotal as 'Total Sales from Customers'
from (
select sales.saledate, sum(sales.saleamt) as All_Total
from Sales
group by sales.saledate
) s1
inner join
(
select sales.saledate, sum(sales.saleamt) as CustomersTotal
from Sales
where sales.customerid in (select customerid from customers)
group by sales.saledate
) s2 on s1.saledate = s2.saledate
you can combine it in one single query using case expression.
select s.saledate,
sum(s.saleamt) as [Total Sales from All],
sum(case when exists
(
select *
from customers c
where c.customerid = s.customerid
)
then s.salesamt
end) as [Total Sales from Customers]
from Sales s
group by s.saledate
You can use a LEFT JOIN with conditional aggregation
select
s.saledate,
sum(s.saleamt) as [Total Sales from All],
sum(case when c.customerid is not null then s.saleamt end) as [Total Sales from Customers]
from Sales s
left join customers c on s.customerid = c.customerid
group by s.saledate;

SQL Server Two Column Pivot table

I'm trying to create a PIVOT TSQL statment that totals the products by date and state/province and provides the AVG Transit Time. Here is what I have so far:
select *
from (select createdate [Date Processed],
stateprovince as [Province],
count(*) as [Total],
avg(datediff(day,createdate,t.eventdate)) as [AVG Delivery],
product
from recipient C left outer join
(select delivid, product, eventdesc, eventdate, eventcode
from deliverystatus
where delivid in (select max(deliv_id)
from deliverystatus
where eventcode = 'DELIVERED'
group by product)) as t ON c.product = t.product
where account = 3519 and consol <>'' and trknum <> '' and C.createdate between '2/4/2016' and '2/4/2016'
group by C.createdate, c.stateprovince, c.product
) as Q
pivot (
count(product)
for [Province] in (NY, IL, GA)
) as PVT
My Result is:
Date Processed Total AVG Transit NY IL GA
2016-02-04 00:00:00.000 1 8 0 0 1
2016-02-04 00:00:00.000 1 11 2 4 1
2016-02-04 00:00:00.000 1 12 0 0 0
2016-02-04 00:00:00.000 1 15 0 0 0
I need the result to be:
Date Processed Total AVG Transit NY IL GA
2016-02-04 00:00:00.000 8 11.5 2 4 2
The ultimate goal is to have the AVG Transit listed by State/Province like this:
Date Processed Total Total AVG NY AVG IL AVG GA AVG
2016-02-04 00:00:00.000 8 11.5 2 8 4 11 2 15
Thanks in advance.
You need to add a GROUP BY clause after the pivot and either take the AVG SUM or MAX value for each output column:
select [Date Processed], SUM(NY+IL+GA) AS [Total], AVG([AVG Delivery]) AS [AVG Delivery], SUM(NY) AS NY, SUM(IL) AS IL, SUM(GA) AS GA
from (select createdate [Date Processed],
stateprovince as [Province],
count(*) as [Total],
avg(datediff(day,createdate,t.eventdate)) as [AVG Delivery],
product
from recipient C left outer join
(select delivid, product, eventdesc, eventdate, eventcode
from deliverystatus
where delivid in (select max(deliv_id)
from deliverystatus
where eventcode = 'DELIVERED'
group by product)) as t ON c.product = t.product
where account = 3519 and consol <>'' and trknum <> '' and C.createdate between '2/4/2016' and '2/4/2016'
group by C.createdate, c.stateprovince, c.product
) as Q
pivot (
count(product)
for [Province] in (NY, IL, GA)
) as PVT
group by [Date Processed]

Get all funds which has at least minimum data points

I have two tables
1) Fund details
ID Symbol
-------------------
1 ABC
2 XYZ
2) Fund Price data
Fund_id date Price
-------------------------------------------
1 2014-07-01 00:00:00.000 25.25
1 2014-07-02 00:00:00.000 25.45
......
2 2014-07-01 00:00:00.000 75.25
2 2014-07-02 00:00:00.000 75.42
.......
Now what I want to achieve is:
Here I am fetching the monthly data of a particular Fund as below:
SELECT YEAR(date) [Year], MONTH(date) [Month],
DATENAME(MONTH,date) [Month Name], COUNT(1) [Sales Count], F.Symbol
FROM FundData FD inner join FundDetails F on F.ID = FD.Fund_ID
where F.Symbol = 'ABC'
GROUP BY YEAR(date), MONTH(date), DATENAME(MONTH, date), F.Symbol
Output:
Year Month Month Name Sales Count Symbol
-------------------------------------------
2014 4 April 21 ABC
2014 5 May 21 ABC
2014 6 June 21 ABC
2014 7 July 3 ABC
.......
Total Rows: 301
So here this is only for only particular fund which has returned 301 rows.
Now I want to get all the funds from the Fund details table which has rows less than given count ex 216 which I will pass as a parameter
Use Following query:
Declare #YourParameter int = 10
SELECT YEAR(date) [Year],
MONTH(date) [Month],
DATENAME(MONTH,date) [Month Name],
COUNT(1) [Sales Count],
F.Symbol
FROM FundData FD
INNER JOIN FundDetails F on FD.ID = F.Fund_ID
Where FD.ID IN (SELECT z.Fund_ID
FROM FundDetails z
WHERE z.Fund_ID=FD.ID
GROUP BY z.Fund_ID, YEAR(z.date), MONTH(z.date)
HAVING COUNT(*) <= #YourParameter
)
GROUP BY YEAR(date), MONTH(date), DATENAME(MONTH, date), F.Symbol
I have fixed it:
Declare #YourParameter int = 110
WITH CTE AS
(
SELECT YEAR(date) [Year], MONTH(date) [Month],
DATENAME(MONTH,date) [Month Name], COUNT(1) [Sales Count], F.Symbol
FROM FundData FD inner join FundDetails F on F.ID = FD.Fund_ID
where F.ID
IN (SELECT z.ID FROM FundDetails z)
GROUP BY F.Symbol, YEAR(date), MONTH(date), DATENAME(MONTH, date)
)
SELECT Symbol, COUNT(*) as cnt FROM CTE
GROUP BY Symbol
having COUNT(*) >= #YourParameter

How to get total sum

I have two tables.
Sales
------
ID Charge VAT
1 100 10
2 200 20
SaleProducts
------------
ID Product Auto SalesID
1 aa True 1
2 bb False 1
I want to get this
SaleOnProduct
-------------
ID Product Charge VAT Total TotalAmount(All of total is plus)
1 aa 100 10 110 220
2 aa 100 10 110 220
How can I do this. Please help me.
declare #Sales table (ID int, Charge int, VAT int)
declare #SaleProducts table (ID int, Product char(2), Auto bit, SalesID int)
insert into #Sales values
(1, 100, 10),
(2, 200, 20)
insert into #SaleProducts values
(1, 'aa', 1, 1),
(2, 'bb', 0, 1)
select
SP.ID,
SP.Product,
S.Charge,
S.VAT,
S.Charge+S.VAT as Total,
sum(S.Charge+S.VAT) over() as TotalAmount
from #Sales as S
inner join #SaleProducts as SP
on S.ID = SP.SalesID
In order to get data from both tables in the same resultset you need to do a join.
Since you want to have a summary row for all sales ((charge+VAT)*numberofSaleProductsRows) of each particular product, you need to use the SUM aggregate funciton, and a GROUP BY clause. All the columns which you need in your resultset and which do not have a specified aggregation needs to be included in the GROUP BY list.
Disclaimer: Untested code
SELECT ID, Product, Charge ,VAT, Charge + VAT as Total,
Sum(Charge + VAT) as TotalAmount
FROM Sales INNER JOIN SaleProducts
ON Sales.ID = SaleProducts.SalesID
GROUP BY ID, Product, Charge, VAT, Charge + VAT
This query do the job: (I supposed SQL Server 2005 or above, otherwise you´ve to change the cte by a temp table)
WITH ReportCte as(
SELECT b.Id IdSale,
a.Id IdProduct,
a.Product,
b.Charge,
b.VAT,
b.Charge+b.VAT Total
FROM [dbo].[SaleProducts] a left join
[dbo].[Sales] b on a.[SalesID] = b.ID)
SELECT a.IdProduct,
a.IdProduct,
a.Charge,
a.VAT,
a.Total,
b.TotalAmount
FROM ReportCte a left join
(select IdSale,SUM(Total) TotalAmount
from ReportCte group by IdSale) b on a.IdSale=b.IdSale
select *, (charge+VAT) as total, SUM(charge+VAT) as totalAmount
from sales
join saleproducts on sales.ID=saleproducts.salesID
group by sales.ID

Resources