I need help with this. I have this SQL statement:
ALTER proc [dbo].[GetDSR]
(
#WholeSellerId varchar(50),
#FromDate date
)
as
begin
with cte1 as
(select co.ProductId as copid, co.DateAdded as coda, sum(isnull(co.quantity,0)) as coq, co.WholeSellerId as coid
from ConsignmentSale co
group by co.ProductId, co.DateAdded, co.WholeSellerId),
cte2 as
(select ca.ProductId as caid, sum(isnull(ca.quantity,0)) as caq from CashSale ca
group by ca.ProductId),
cte3 as
(select wi.ProductId as wiid, sum(isnull(wi.Quantity,0)) as wiq from Withdrawal wi
group by wi.ProductId),
cte4 as
(select po.ProductId as poid, sum(isnull(po.Quantity,0)) as poq from Pullout po
group by po.ProductId),
cte5 as
(select pr.ProductId as prid, sum(isnull(pr.Quantity,0)) as prq from Promotion pr
group by pr.ProductId)
select cte1.copid as Product, cte1.coda, isnull(cte1.coq,0) as Credit, isnull(cte2.caq,0) as Cash,
isnull(cte3.wiq,0) as Withdrawal, isnull(cte4.poq,0) as Pullout, isnull(cte5.prq,0) as Promotion
from cte1
full outer join cte2 on cte2.caid=cte1.copid
full outer join cte3 on cte3.wiid=cte1.copid
full outer join cte4 on cte4.poid=cte1.copid
full outer join cte5 on cte5.prid=cte1.copid
where cte1.coid = #WholeSellerId and cte1.coda = #FromDate
end
go
It gives me the right result only when there is a data in the ConsignmentSale that meets the specific condition. The problem is, when there is no data in the ConsignmentSale that meets the condition but there is in some other table, it is not displayed. Probably it is because of this part:
where cte1.coid = #WholeSellerId and cte1.coda = #FromDate
It is only using the criteria in a single table, the ConsignmentSale, and it does not check the rest of the table for this criteria. Please show me how to alter this procedure in such a way that even if in the ConsignmentSale the criteria is not met but in the other table it is met, it will still give me result and the coq is just going to be 0 since it does not have data that adheres to that criteria.
Thank you.
Move the filter's to ON condition
................
FROM cte1
FULL OUTER JOIN cte2
ON cte2.caid = cte1.copid
AND cte1.coid = #WholeSellerId
AND cte1.coda = #FromDate
FULL OUTER JOIN cte3
ON cte3.wiid = cte1.copid
FULL OUTER JOIN cte4
ON cte4.poid = cte1.copid
FULL OUTER JOIN cte5
ON cte5.prid = cte1.copid
.................
I just created a criteria on each statement like so:
ALTER proc [dbo].[GetDSR]
(
#WholeSellerId varchar(50),
#FromDate date
)
as
begin
with
cte1 as
(select pr.ProductId from Product pr),
cte2 as
(select co.WholeSellerId as cowi, co.DateAdded as coda, co.ProductId as coid, sum(isnull(co.Quantity,0)) as coq from ConsignmentSale co
where co.WholeSellerId=#WholeSellerId and co.DateAdded=#FromDate
group by co.ProductId, co.DateAdded, co.WholeSellerId),
cte3 as
(select ca.DateAdded as cada, ca.WholeSellerId as cawi, ca.ProductId as caid, sum(isnull(ca.Quantity,0)) as caq from CashSale ca
where ca.WholeSellerId=#WholeSellerId and ca.DateAdded=#FromDate
group by ca.ProductId, ca.WholeSellerId, ca.DateAdded),
cte4 as
(select pm.DateAdded as pmda, pm.ProductId as pmid, pm.WholeSellerId as pmwi, sum(isnull(pm.Quantity,0)) as pmq from Promotion pm
where pm.WholeSellerId=#WholeSellerId and pm.DateAdded=#FromDate
group by pm.DateAdded, pm.ProductId, pm.WholeSellerId),
cte5 as
(select wi.ProductId as wiid, wi.DateAdded as wida, wi.WholeSellerId as wiwi, sum(isnull(wi.Quantity,0)) as wiq from Withdrawal wi
where wi.WholeSellerId=#WholeSellerId and wi.DateAdded=#FromDate
group by wi.DateAdded, wi.WholeSellerId, wi.ProductId),
cte6 as
(select po.ProductId as poid, po.DateAdded as poda, po.WholeSellerId as powi, sum(isnull(po.Quantity,0)) as poq from Pullout po
where po.WholeSellerId=#WholeSellerId and po.DateAdded=#FromDate
group by po.ProductId, po.DateAdded, po.WholeSellerId)
select cte1.ProductId as 'Product', isnull(cte2.coq,0) as 'Credit', isnull(cte3.caq,0) as 'Cash', isnull(cte5.wiq,0) as 'Withdrawal',
isnull(cte6.poq,0) as 'Pullout', isnull(cte4.pmq,0) as 'Promotion'
from cte1
full outer join cte2 on cte2.coid = cte1.ProductId
full outer join cte3 on cte3.caid=cte1.ProductId
full outer join cte4 on cte4.pmid=cte1.ProductId
full outer join cte5 on cte5.wiid=cte1.ProductId
full outer join cte6 on cte6.poid=cte1.ProductId
end
Related
I'm trying to calculate list all Customers A/C Receivables.
I calculate list of sales and receipts of customers, now I'm stuck how to calculate Receivables.
All Customer's Sales Report
Select c.StakeHolderId, c.CompanyName, sum(s.Amount) as TotalSales from
StakeHolders c
left Join Sales s on
c.StakeHolderId = s.BuyerId
where c.StakeHolderTypeId = '0b85a69e-55f2-4142-a49d-98e22aa7ca10'
group By c.StakeHolderId, c.CompanyName
All Customer's Receipts
Select c.StakeHolderId, c.CompanyName, sum(pr.Amount) as TotalReceipts
from
StakeHolders c
left Join PaymentsAndReceipts pr on
c.StakeHolderId = pr.StakeHolderId
where c.StakeHolderTypeId = '0b85a69e-55f2-4142-a49d-98e22aa7ca10'
group By c.StakeHolderId, c.CompanyName
I have tried this but didn't get the right result.
Select
c.StakeHolderId,
c.CompanyName,
sum(s.Amount) - sum(pr.Amount) as Receivables
from Sales s
right outer join StakeHolders c on
c.StakeHolderId = s.BuyerId
left outer join PaymentsAndReceipts pr on
pr.StakeHolderId = c.StakeHolderId
where c.StakeHolderTypeId = '0b85a69e-55f2-4142-a49d-98e22aa7ca10'
Group By c.StakeHolderId,c.CompanyName
expected Result:
Does this work for you?:
WITH [CalculatedData] AS
(
SELECT
C.[StakeHolderId],
C.[CompanyName],
COALESCE((SELECT SUM([Amount])
FROM [Sales]
WHERE [BuyerId] = C.[StakeHolderId]
), 0) AS [TotalSales],
COALESCE((SELECT SUM([Amount])
FROM [PaymentsAndReceipts]
WHERE [StakeHolderId] = C.[StakeHolderId]
), 0) AS [TotalReceipts]
FROM
[StakeHolders] AS C
WHERE
C.[StakeHolderTypeId] = '0b85a69e-55f2-4142-a49d-98e22aa7ca10'
)
SELECT
[StakeHolderId],
[CompanyName],
[TotalSales] - [TotalReceipts] AS [Receivables]
FROM
[CalculatedData]
Note that I include negative values in the result. If you want negative values shown between parentheses, that's possible too, but it will require conversion of numerical data to textual data in the query results. IMHO, that's not a flexible strategy (since you lose the option to perform any additional client-side calculations) and it should be the client's purpose to correctly format the values.
Edit:
If you don't like Common Table Expressions, you can convert it to a regular table expression:
SELECT
[StakeHolderId],
[CompanyName],
[TotalSales] - [TotalReceipts] AS [Receivables]
FROM
(
SELECT
C.[StakeHolderId],
C.[CompanyName],
COALESCE((SELECT SUM([Amount])
FROM [Sales]
WHERE [BuyerId] = C.[StakeHolderId]
), 0) AS [TotalSales],
COALESCE((SELECT SUM([Amount])
FROM [PaymentsAndReceipts]
WHERE [StakeHolderId] = C.[StakeHolderId]
), 0) AS [TotalReceipts]
FROM
[StakeHolders] AS C
WHERE
C.[StakeHolderTypeId] = '0b85a69e-55f2-4142-a49d-98e22aa7ca10'
) AS [CalculatedData]
just take first query LEFT JOIN to second query join by StakeHolderId & companyname. After that take sales subtract receipts
SELECT S.StakeHolderId, S.CompanyName,
Receivables = TotalSales - ISNULL(TotalReceipts , 0)
FROM
(
-- this is your first query
Select c.StakeHolderId, c.CompanyName, sum(s.Amount) as TotalSales from
StakeHolders c
left Join Sales s on
c.StakeHolderId = s.BuyerId
where c.StakeHolderTypeId = '0b85a69e-55f2-4142-a49d-98e22aa7ca10'
group By c.StakeHolderId, c.CompanyName
) S
LEFT JOIN
(
-- this is your second query
Select c.StakeHolderId, c.CompanyName, sum(pr.Amount) as TotalReceipts
from
StakeHolders c
left Join PaymentsAndReceipts pr on
c.StakeHolderId = pr.StakeHolderId
where c.StakeHolderTypeId = '0b85a69e-55f2-4142-a49d-98e22aa7ca10'
group By c.StakeHolderId, c.CompanyName
) R ON S.StakeHolderId = R.StakeHolderId
AND S.CompanyName = R.CompanyName
I need a query for [Contribution]. I used this query:
with ttt as
(
select
(DYG.U_StyleId)[DYG Style]
,Max(O1.CardCode) [Party Group Code],
MAX(O1.CardName) [Party Group Name]
,MAX(OR1.DocDate) [Date]
,sum(CONVERT(NUMERIC(15,2),(RDR1.PriceBefDi*RDR1.Quantity))) [JobAmount]
,CONVERT(NUMERIC(15,2),SUM(RDR1.Quantity)) [Mtr]
,CONVERT(NUMERIC(15,2),SUM(RDR1.U_Pcs))[Pcs]
,(select sum(RDR1.PriceBefDi*RDR1.Quantity) from RDR1) tqty
from
ORDR OR1
left join RDR1 on RDR1.DocEntry = OR1.DocEntry
left join OITM on RDR1.ItemCode = oitm.ItemCode
LEFT JOIN OCRD ON OCRD.CardCode = OR1.CardCode
LEFT JOIN OCRG ON OCRG.GroupCode = OCRD.GroupCode
LEFT JOIN OCRD O1 ON O1.U_BCode = OCRD.U_GrpCod
LEFT JOIN
( SELECT U_StyleId FROM RDR1 WHERE U_StyleId in
('BLOOM','BLOOMING','DYD','DYD-R','DYED','Ex.CLR.','RAINBOW'))
DYG ON DYG.U_StyleId = RDR1.U_StyleId
group by
DYG.U_StyleId
)
select
Style, [Party Group Code],
[Party Group Name], JobAmount,
(sum(JobAmount) / tqty * 100) [Contribution],
[Date], [Pcs]
from
ttt
group by
Style
I need Sum of last jobamount to divide it with above tqty.
But it shows this error.
'Column 'ttt.Party Group Code' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.'
Please help me with the query to get right [Contribution] amount.
Try this:
select Style,[Party Group Code],[Party Group Name],JobAmount,[Date],[Pcs],
100.0 * (sum(JobAmount) OVER (PARTITION BY Style))/tqty [Contribution]
from ttt;
I am learning window functions in sql server. I am using AdventrueWorks2012 database for practice. I want to calculate total number of sales and purchases for each item in the store.
The classic solution can be like
SELECT ProductID,
Quantity,
(SELECT Count(*)
FROM AdventureWorks.Purchasing.PurchaseOrderDetail
WHERE PurchaseOrderDetail.ProductID = p.ProductID) TotalPurchases,
(SELECT Count(*)
FROM AdventureWorks.Sales.SalesOrderDetail
WHERE SalesOrderDetail.ProductID = p.ProductID) TotalSales
FROM (SELECT DISTINCT ProductID,
Quantity
FROM AdventureWorks.Production.ProductInventory) p
Trying to convert to window functions gives me wrong results:
SELECT DISTINCT d.ProductID,
Quantity,
Count(d.ProductID)
OVER(
PARTITION BY d.ProductID) TotalPurchases,
Count(d2.ProductID)
OVER(
PARTITION BY d2.ProductID) TotalSales
FROM (SELECT DISTINCT ProductID,
Quantity
FROM AdventureWorks.Production.ProductInventory) p
INNER JOIN AdventureWorks.Purchasing.PurchaseOrderDetail d
ON p.ProductID = d.ProductID
INNER JOIN AdventureWorks.Sales.SalesOrderDetail d2
ON p.ProductID = d2.ProductID
ORDER BY d.ProductID
Why this is wrong? How can I correct it?
You should change INNER JOIN to LEFT JOIN
Because when you inner join, result will miss productid which from ProductInventory table does not have PurchaseOrderDetail or SalesOrderDetail.
Can someone help me with this query? I want to get the result of all the customer_id which repeats more than once in 24hrs
SELECT
O.Order_No, O.Customer_ID, O.DateOrdered, O.IPAddress,
C.FirstName, C.LastName, CD.nameoncard
FROM
Order_No O
INNER JOIN
CardData CD ON O.card_id = CD.id
INNER JOIN
Customers C ON O.customer_id = C.customer_id
ORDER BY
O.order_no desc
adding more details..
so suppose order with customer id xx was placed on 04/23 2:30 pm and again 2nd order was placed with same customer Id xx on same day 04/23 5:30 pm.
i want the query to return me customer Id xx
Thanks
select Customer_ID, CAST(DateOrdered as Date) DateOrdered, count(*) QTDE
from Order_No
group by Customer_ID, CAST(DateOrdered as Date)
having count(*) > 1
To get the customers who have orders issued after the first one, then you could use the following query:
select distinct A.Customer_ID
from Order_No A
inner join (select Customer_ID, min(DateOrdered) DateOrdered from Order_No group by Customer_ID ) B
on A.Customer_ID = B.Customer_ID
and A.DateOrdered - B.DateOrdered <= 1
and A.DateOrdered > B.DateOrdered
SQL Fiddle
To get all customers that have ANY TIME more than one order issued in period less or equal than 24h
select distinct A.Customer_ID
from Order_No A
inner join Order_No B
on A.Customer_ID = B.Customer_ID
and A.DateOrdered > B.DateOrdered
and A.DateOrdered - B.DateOrdered <= 1
SQL Fiddle
Self-join:
SELECT distinct O.Customer_ID
FROM
Order_No O
inner join Order_No o2
on o.customerID = o2.customerID
and datediff(hour, o.DateOrdered, o2.DateOrdered) between 0 and 24
and o.Order_No <> o2.Order_No
This will return all customer_IDs that have ever placed more than one order in any 24 hour period.
Edited to add the join criteria that the matching records should not be the same record. Should return customers who placed two different orders at the same time, but not customers who placed only one order.
So this is what i thought of doing but now the error i am getting is : Cannot use an aggregate or a subquery in an expression used for the group by list of a GROUP BY clause and not sure which part it means - the overall code i am trying to get open cases based on two different levels one is to return cases based on date range passed in and the other is to return cases based on just the begin date and before it.
Help will be great! :)
CODE:
SELECT
C.CaseNumber,
O.OfficeName,
CT.Description AS CaseType,
DATEADD(dd, 0, DATEDIFF(dd, 0, C.DateOpened)) AS DateOpened,
CR.Description AS Court,
CaseOfficeAppointment.OpenCases,
CaseOfficeAppointment.CloseCases
FROM
(
SELECT C.CaseId, O.OfficeId, CRT.CourtId,
(
SELECT COUNT(DISTINCT CD.CaseId)
FROM [Case] CD
INNER JOIN CaseOffice COD ON CD.CaseId = COD.CaseId
--INNER JOIN Court CR ON CD.CourtId = CR.CourtId
INNER JOIN Office OD ON COD.OfficeId = OD.OfficeId
LEFT OUTER JOIN CaseStatusChange CSC ON CD.CaseId = CSC.CaseId
--WHERE CR.CourtId = CRT.CourtId
WHERE OD.OfficeId = O.OfficeId
AND
( CD.DateOpened BETWEEN #BeginDate AND #EndDate
OR
CSC.DateReopened BETWEEN #BeginDate AND #EndDate
)
)AS OpenCases,
(
SELECT COUNT(DISTINCT CD.CaseId)
FROM [Case] CD
INNER JOIN CaseOffice COD ON CD.CaseId = COD.CaseId
--INNER JOIN Court CR ON CD.CourtId = CR.CourtId
INNER JOIN Office OD ON COD.OfficeId = OD.OfficeId
LEFT OUTER JOIN CaseStatusChange CSC ON CD.CaseId = CSC.CaseId
--WHERE CR.CourtId = CRT.CourtId
WHERE OD.OfficeId = O.OfficeId
AND
( CSC.DateClosed BETWEEN #BeginDate AND #EndDate
)
)AS CloseCases
FROM [Case] C
INNER JOIN [Appointment] A ON C.CaseId = A.CaseId
INNER JOIN [Office] O ON A.OfficeId = O.OfficeId
INNER JOIN [Court] CRT ON C.CourtId = CRT.CourtId
WHERE
-- Case was open (or reopened) during the date range
C.DateOpened BETWEEN #beginDate AND #endDate
OR
C.CaseId IN (SELECT CaseId FROM CaseStatusChange WHERE DateReopened BETWEEN #beginDate AND #endDate)
AND
-- Office had an appointment sometime during the date range
A.DateOn < #endDate AND (A.DateOff IS NULL OR A.DateOff BETWEEN #beginDate AND #endDate)
GROUP BY C.CaseId, O.OfficeId, CRT.CourtId,
(
SELECT OfficeId, SUM(CaseCount)AS Counts
FROM (
SELECT COUNT(C.CaseId) AS CaseCount,O.OfficeId
FROM [Case] C
INNER JOIN [Appointment] A ON C.CaseId = A.CaseId
INNER JOIN [Office] O ON A.OfficeId = O.OfficeId
WHERE C.DateCreated <= #BeginDate
AND C.CaseId NOT IN (SELECT CaseId FROM CaseStatusChange CSC WHERE CSC.DateClosed < #BeginDate)
--GROUP BY O.OfficeId
UNION
-- Also need the cases that reopened and are currently open
SELECT COUNT(ReOpened.CaseId) As CaseCount, ReOpened.OfficeID
FROM (
SELECT C.CaseId, MAX(CSC.DateReopened) AS DateReOpened, O.OfficeId
FROM [Case] C
INNER JOIN [CaseStatusChange] CSC ON C.CaseId = CSC.CaseId
INNER JOIN [Appointment] A ON C.CaseId = A.CaseId
INNER JOIN [Office] O ON A.OfficeId = O.OfficeId
WHERE CSC.DateReopened <= #BeginDate
--GROUP BY C.CaseId, O.OfficeID
) AS ReOpened
WHERE ReOpened.CaseId NOT IN
(
SELECT CaseId FROM CaseStatusChange
WHERE CaseId = ReOpened.CaseId AND
CaseStatusChange.DateClosed BETWEEN ReOpened.DateReopened AND #BeginDate
)
GROUP BY ReOpened.OfficeId
) AS OpenCasesCount
GROUP BY OfficeId
)
)
CaseOfficeAppointment
INNER JOIN [Case] C ON CaseOfficeAppointment.CaseId = C.CaseId
INNER JOIN [Office] O ON CaseOfficeAppointment.OfficeId = O.OfficeId
INNER JOIN [CaseType] CT ON C.CaseTypeId = CT.CaseTypeId
INNER JOIN [Court] CR ON C.CourtId = CR.CourtId
If I understood you right, you need something like :
CREATE PROCEDURE new_proc
AS
BEGIN
DECLARE #tmp_proc1 TABLE (// list all fields your first procedure returns );
DECLARE #tmp_proc2 TABLE (// list fields that your second SP returns);
INSERT INTO #tmp_proc1
EXECUTE Your_First_Procedure ;
INSERT INTO #tmp_proc2
EXECUTE Your_Second_Procedure;
// Finally, join data in #tmp_proc1 and #tmp_proc2
//(you probably need FULL JOIN) and return 1 resultset
END;
Provided you adjust the header to add all parameters needed, you can add as many result sets to a stored procedure as you need. Consuming the multiple tables will vary based on the language and platform you are using to consume the data, but simply result set from one sproc into the other should work fine, unless there is a limitation in the underlying data store (database server?).
ADDED:
Based on your response, you can combined the two results sets in a single stored procedure. To consume this, you have a variety of options. With a Reader, you can go to next result set, as it is a firehose cursor. But, it might be easier to use something like a DataSet and have it generated form the stored procedure. you can then use a table adapter to fill the data set from the stored procedure. Both tables should be filled now with a single call.
Does this make sense?