Sum group of rows based on value in a column - sql-server

I am new to SQL and I have the below tables
that I need to select and get the desired result below.

Try a query like below.
select
[Account Group] =AG.Name,
[Ledger Name] =AL.Name,
DR =SUM(CASE WHEN TT.Name='DR' THEN Amount ELSE NULL END),-- case based SUM expression
CR =SUM(CASE WHEN TT.Name='CR' THEN Amount ELSE NULL END)
from Account_Group AG
join Account_ledgers AL -- NOTE we have used INNER JOIN throughout
on AG.Id=AL.AccountGroupId
join Transactions T
on T.AccountLedgerId=AL.Id
join Transaction_Type TT
on TT.Id= T.TransactionTypeId
group by AG.Name,AL.Name -- Group by contains all the things we need in SELECT list

Related

Two IDs matching one causing duplicates

I am trying to inner join however I keep getting this duplicate pop up where there are two job IDs matching one Invoice ID (inner joined with a middle table that links both).
I want to only get 1 invoice id and summing the total despite 2 job ids matching it.
Basically there is AINVOICEID (table:Invoice ) matching ABINVOICEID (table:INLines) and inside the INLines table, it contains ARJOBID that matches the JOBID in Jobs.
Select distinct sum(totalBASE) as InvoiceTotal,
DATEADD(MONTH, DATEDIFF(MONTH, 0, InvDate), 0)
from (select distinct left(JOBID,5)as JOBID
from jobs
group by JOBID
) jobs
inner join (select distinct ABINVOICEID, left(ARLJOBID,5) as arljobid
from INLines
group by ARLJOBID, ABINVOICEID
) INLines
on left(ARLJOBID,5) = left(JOBID,5)
inner join (select distinct AINVOICEID
, sum(totalBASE) as totalBASE
, InvDate
from Invoice
group by AINVOICEID, InvDate
) Invoice
on AINVOICEID = ABINVOICEID
where left(JOBID ,5)=left(ARLJOBID,5) and AINVOICEID = ABINVOICEID
and InvDate between '05/01/2022' AND '05/31/2022'
group by left(JOBID ,5), DATEADD(MONTH, DATEDIFF(MONTH, 0, InvDate), 0)
It is quite difficult to try and make sense of what you're asking without an example of the output that you're getting and what the expected output is.
However, I think you're wanting something like this:
SELECT I.AINVOICEID, SUM(I.totalBASE) AS totalBASE, InvDate
FROM Invoice I INNER JOIN
(
SELECT L.ABINVOICEID, J.JOBID
FROM INLines L INNER JOIN
Jobs J ON L.ARLJOBID = J.JOBID
GROUP BY L.ABINVOICEID, J.JOBID
) LJ ON I.AINVOICEID = L.ABINVOICEID
WHERE I.InvDate BETWEEN '05/01/2022' AND '05/31/2022'
GROUP BY I.AINVOICEID, InvDate
This is based on what your SQL query which doesn't really look like it needs to JOIN on the INLines or Jobs table because you're getting everything you need from the Invoice table in the SELECT ?
If this isn't what you're after, if you can elaborate a bit more, then the community on here should be able to better assist with your question.

SQL boolean EXISTS while using aggregate function

I have written a query that returns the list of all customers that have ever made a purchase with the company I work for. The person for whom I am getting the data would like to know if a specific criteria is true for any of these orders.
select L.ParentLocation,
[Number of Orders] = count(distinct(T.Order))
from Table1 L
join Table2 T
on L.Location = T.Location
group by L.ParentLocation
However, the issue is complicated because I am already grouping by ParentLocation, and each ParentLocation has many normal Locations. So I am counting the number of unique orders at the location level, then grouping them by the ParentLocation.
I want to return 'TRUE' in the query if a field 'OrderDesc' contains "Toys" in ANY of the orders by ANY of the Locations owned by a ParentLocation. Is there a way to do this?
NOTE: Table2 contains the OrderDesc column.
Thanks for reading!
select
L.ParentLocation,
[Number of Orders] = count(distinct(T.Order)),
has_toys = max(case when t.OrderDesc like '%toys%' then 'TRUE' else '' end)
from Table1 L
inner join Table2 T
on L.Location = T.Location
group by
L.ParentLocation

Why do I have duplicate records in my JOIN

I am retrieving data from table ProductionReportMetrics where I have column NetRate_QuoteID. Then to that result set I need to get Description column.
And in order to get a Description column, I need to join 3 tables:
NetRate_Quote_Insur_Quote
NetRate_Quote_Insur_Quote_Locat
NetRate_Quote_Insur_Quote_Locat_Liabi
But after that my premium is completely off.
What am I doing wrong here?
SELECT QLL.Description,
QLL.ClassCode,
prm.NetRate_QuoteID,
QL.LocationID,
ISNULL(SUM(premium),0) AS NetWrittenPremium,
MONTH(prm.EffectiveDate) AS EffMonth
FROM ProductionReportMetrics prm
LEFT JOIN NetRate_Quote_Insur_Quote Q
ON prm.NetRate_QuoteID = Q.QuoteID
INNER JOIN NetRate_Quote_Insur_Quote_Locat QL
ON Q.QuoteID = QL.QuoteID
INNER JOIN NetRate_Quote_Insur_Quote_Locat_Liabi QLL
ON QL.LocationID = QLL.LocationID
WHERE YEAR(prm.EffectiveDate) = 2016 AND
CompanyLine = 'Ironshore Insurance Company'
GROUP BY MONTH(prm.EffectiveDate),
QLL.Description,
QLL.ClassCode,
prm.NetRate_QuoteID,
QL.LocationID
I think the problem in this table:
What Am I missing in this Query?
select
ClassCode,
QLL.Description,
sum(Premium)
from ProductionReportMetrics prm
LEFT JOIN NetRate_Quote_Insur_Quote Q ON prm.NetRate_QuoteID = Q.QuoteID
LEFT JOIN NetRate_Quote_Insur_Quote_Locat QL ON Q.QuoteID = QL.QuoteID
LEFT JOIN
(SELECT * FROM NetRate_Quote_Insur_Quote_Locat_Liabi nqI
JOIN ( SELECT LocationID, MAX(ClassCode)
FROM NetRate_Quote_Insur_Quote_Locat_Liabi GROUP BY LocationID ) nqA
ON nqA.LocationID = nqI.LocationID ) QLL ON QLL.LocationID = QL.LocationID
where Year(prm.EffectiveDate) = 2016 AND CompanyLine = 'Ironshore Insurance Company'
GROUP BY Q.QuoteID,QL.QuoteID,QL.LocationID
Now it says
Msg 8156, Level 16, State 1, Line 14
The column 'LocationID' was specified multiple times for 'QLL'.
It looks like DVT basically hit on the answer. The only reason you would get different amounts(i.e. duplicated rows) as a result of a join is that one of the joined tables is not a 1:1 relationship with the primary table.
I would suggest you do a quick check against those tables, looking for table counts.
--this should be your baseline count
SELECT COUNT(*)
FROM ProductionReportMetrics
GROUP BY MONTH(prm.EffectiveDate),
prm.NetRate_QuoteID
--this will be a check against the first joined table.
SELECT COUNT(*)
FROM NetRate_Quote_Insur_Quote Q
WHERE QuoteID IN
(SELECT NetRate_QuoteID
FROM ProductionReportMetrics
GROUP BY MONTH(prm.EffectiveDate),
prm.NetRate_QuoteID)
Basically you will want to do a similar check against each of your joined tables. If any of the joined tables are part of the grouping statement, make sure they are also in the grouping of the count check statement. Also make sure to alter the WHERE clause of the check count statement to use the join clause columns you were using.
Once you find a table that returns the incorrect number of rows, you will have your answer as to what table is causing the problem. Then you will just have to decide how to limit that table down to distinct rows(some type of aggregation).
This advice is really just to show you how to QA this particular query. Break it up into the smallest possible parts. In this case, we know that it is a join that is causing the problem, so take it one join at a time until you find the offender.

Using the results of WITH clause IN where STATEMENT of main query

I am relatively new at SQL so I apologise if this is obvious but I cannot work out how to use the results of the WITH clause query in the where statement of my main query.
My with query pulls the first record for each customer and gives the sale date for that record:
WITH summary AS(
SELECT ed2.customer,ed2.saledate,
ROW_NUMBER()OVER(PARTITION BY ed2.customer
ORDER BY ed2.saledate)AS rk
FROM Filteredxportdocument ed2)
SELECT s.*
FROM summary s
WHERE s.rk=1
I need to use the date in the above query as the starting point and pull all records for each customer for their first 12 months i.e. where the sale date is between ed2.saledate AND ed2.saledate+12 months.
My main query is:
SELECT ed.totalamountincvat, ed.saledate, ed.name AS SaleRef,
ed.customer, ed.customername, comp.numberofemployees,
comp.companyuid
FROM exportdocument AS ed INNER JOIN
FilteredAccount AS comp ON ed.customer = comp.accountid
WHERE (ed.statecode = 0) AND
ed.saledate BETWEEN ed2.saledate AND DATEADD(M,12,ed2.saledate)
I am sure that I need to add the main query into the WITH clause but I cant work out where. Is anyone able to help please
Does this help?
;WITH summary AS(
SELECT ed2.customer,ed2.saledate,
ROW_NUMBER()OVER(PARTITION BY ed2.customer
ORDER BY ed2.saledate)AS rk
FROM Filteredxportdocument ed2)
SELECT ed.totalamountincvat, ed.saledate, ed.name AS SaleRef,
ed.customer, ed.customername, comp.numberofemployees,
comp.companyuid
FROM exportdocument AS ed INNER JOIN
FilteredAccount AS comp ON ed.customer = comp.accountid
OUTER APPLY (SELECT s.* FROM summary s WHERE s.rk=1) ed2
WHERE ed.statecode = 0 AND
ed.saledate BETWEEN ed2.saledate AND DATEADD(M,12,ed2.saledate)
and ed.Customer = ed2.Customer
Results of CTE are not cached or stored, so you can't reuse it.
EDIT:
Based upon your requirement that all the records from CTE should be in final result, this is a new query:
;WITH summary AS(
SELECT ed2.customer,ed2.saledate,
ROW_NUMBER()OVER(PARTITION BY ed2.customer
ORDER BY ed2.saledate)AS rk
FROM Filteredxportdocument ed2)
SELECT
ed.totalamountincvat,
ed.saledate,
ed.name AS SaleRef,
ed.customer,
ed.customername,
comp.numberofemployees,
comp.companyuid
FROM
summary ed2
left join exportdocument ed
on ed.Customer = ed2.Customer
and ed.statecode = 0
AND ed.saledate BETWEEN ed2.saledate AND DATEADD(M,12,ed2.saledate)
INNER JOIN FilteredAccount comp
ON ed.customer = comp.accountid
WHERE
s.rk=1
summary you will be able to use only once. Alternate solution is store summary into temp table and use that as many times as u want.
Something like : Select * into #temp from Summary s where s.rk=1

SELECT Specefic Date in Tsql Query?

I have 3 tables that are joined together with this query.
One of them brings me people names , another one brings me their points and the last one brings me date time.
I select the total people score.
Also, there is a column in the 3th tables that brings me the scores' transaction Date Time. My problem is that I want to write a TSQL query with this condition:
Select the transaction date where the people score is 12,000 or more.
In my idea I should use while loop but I do not know the syntax?
This is how I would do it-
SELECT cp.FirstName
, cp.LastName
, SUM(Points) as Score
FROM ClubProfile cp
RIGHT JOIN CardTransaction ct
ON cp.ClubProfileId = ct.ClubProfileId
INNER JOIN Your3rdTable as t3
ON cp.ClubProfileId = t3.ClubProfileId
WHERE CONVERT(VARCHAR, ct.[Date Column], 101) = #your_date_param
GROUP BY
cp.FirstName
, cp.LastName
HAVING SUM(Points) >=12000
Based on your post this should be close to what you need. You need to add that 3rd table and alter this statement accordingly.
SELECT cp.FirstName
, cp.LastName
, SUM(Points) as Score
FROM [fidilio].[dbo].[ClubProfile] cp
RIGHT JOIN (
CardTransaction ct
INNER JOIN CardTransactionLog ctl
ON cp.CardTransactionLogId = ctl.CardTransactionLogId
)
ON cp.ClubProfileId = ct.ClubProfileId
GROUP BY
cp.FirstName
, cp.LastName
HAVING SUM(Points) >=12000
AND ctl.TransactionTimeStamp = #SomeDateTimeVariable
The variable #SomeDateTimeVariable has to come from someplace what is your exact time-frame criteria

Resources