sql - how to sum a dynamically created column with the same id? - sql

select
Cu.CustomerNum, Cu.Name, sum(Cio1.Quantity * C1.Price) AS Total_Income
from
Orders O1
inner join
CoursesInOrder Cio1 on O1.OrderNum = Cio1.OrderNum
inner join
Customer Cu on Cu.CustomerNum = O1.CustomerNum
inner join
Course C1 on C1.CourseNum = Cio1.CourseNum
where
O1.CustomerNum in (select O.CustomerNum
from Course C
inner join CoursesInOrder Cio on C.CourseNum = Cio.CourseNum
inner join Orders O on O.OrderNum= Cio.OrderNum
where C.CourseNum = '99771'
and year(O.Shiftdate) = '2014'
group by O.CustomerNum
having count(O.CustomerNum) > 2)
[Current output]
[Wanted output]
I'm trying to sum the dynamically created solumn - Total_Income,
it keeps giving me almost-random errors,
would appreciate any help!

select
Cu.CustomerNum, Cu.Name, sum(Cio1.Quantity * C1.Price) AS Total_Income
from
Orders O1
inner join
CoursesInOrder Cio1 on O1.OrderNum = Cio1.OrderNum
inner join
Customer Cu on Cu.CustomerNum = O1.CustomerNum
inner join
Course C1 on C1.CourseNum = Cio1.CourseNum
where
O1.CustomerNum in (select O.CustomerNum
from Course C
inner join CoursesInOrder Cio on C.CourseNum = Cio.CourseNum
inner join Orders O on O.OrderNum= Cio.OrderNum
where C.CourseNum = '99771'
and year(O.Shiftdate) = '2014'
group by O.CustomerNum
having count(O.CustomerNum) > 2)
Group by Cu.CustomerNum, Cu.Name

Related

Oracle SQL How to Count Column Value Occurences and Group BY during joins

I'm working on another SQL query, trying to group a collection of records while doing a count and joining tables. See below for goal, current query, and attached scripts for building and populating tables.
Show all customers who have checked more books than DVDs. Display
customer name, total book checkouts and total DVD checkouts. Sort
results by customer first name and last name.
SELECT C.CUSTOMER_FIRSTNAME, C.CUSTOMER_LASTNAME, COUNT(T.TRANSACTION_ID)
FROM customer C
INNER JOIN library_card LC ON C.CUSTOMER_ID = LC.CUSTOMER_ID
INNER JOIN transaction T ON LC.LIBRARY_CARD_ID = T.LIBRARY_CARD_ID
INNER JOIN physical_item P ON T.PHYSICAL_ITEM_ID = P.PHYSICAL_ITEM_ID
INNER JOIN catalog_item CT ON P.CATALOG_ITEM_ID = CT.CATALOG_ITEM_ID
GROUP BY C.CUSTOMER_FIRSTNAME, C.CUSTOMER_LASTNAME
ORDER BY C.CUSTOMER_FIRSTNAME, C.CUSTOMER_LASTNAME;
Run first: https://drive.google.com/open?id=1PYAZV4KIfZtxP4eQn35zsczySsxDM7ls
Run second: https://drive.google.com/open?id=1pAzWmJqvD3o3n6YJqVUM6TtxDafKGd3f
EDIT
With some help from Mr. Barbaros I've come up with the below query, which is closer. However, this query isn't returning any results for DVDs, which leads me to believe it's a join issue.
SELECT C.CUSTOMER_FIRSTNAME, C.CUSTOMER_LASTNAME, COUNT(CT1.TYPE) AS BOOK_COUNT, COUNT(CT2.TYPE) AS DVD_COUNT
FROM customer C
INNER JOIN library_card LC ON C.CUSTOMER_ID = LC.CUSTOMER_ID
INNER JOIN transaction T ON LC.LIBRARY_CARD_ID = T.LIBRARY_CARD_ID
INNER JOIN physical_item P ON T.PHYSICAL_ITEM_ID = P.PHYSICAL_ITEM_ID
INNER JOIN catalog_item CT1 ON P.CATALOG_ITEM_ID = CT1.CATALOG_ITEM_ID AND CT1.TYPE = 'BOOK'
LEFT OUTER JOIN catalog_item CT2 ON P.CATALOG_ITEM_ID = CT2.CATALOG_ITEM_ID AND CT2.TYPE = 'DVD'
GROUP BY C.CUSTOMER_FIRSTNAME, C.CUSTOMER_LASTNAME, CT1.TYPE, CT2.TYPE
ORDER BY C.CUSTOMER_FIRSTNAME, C.CUSTOMER_LASTNAME;
Use "conditional aggregates" (use a case expression inside the aggregate function)
SELECT
C.CUSTOMER_FIRSTNAME
, C.CUSTOMER_LASTNAME
, COUNT( CASE WHEN CT.TYPE = 'BOOK' THEN T.TRANSACTION_ID END ) books
, COUNT( CASE WHEN CT.TYPE = 'DVD' THEN T.TRANSACTION_ID END ) dvds
FROM customer C
INNER JOIN library_card LC ON C.CUSTOMER_ID = LC.CUSTOMER_ID
INNER JOIN transaction T ON LC.LIBRARY_CARD_ID = T.LIBRARY_CARD_ID
INNER JOIN physical_item P ON T.PHYSICAL_ITEM_ID = P.PHYSICAL_ITEM_ID
INNER JOIN catalog_item CT ON P.CATALOG_ITEM_ID = CT.CATALOG_ITEM_ID
GROUP BY
C.CUSTOMER_FIRSTNAME
, C.CUSTOMER_LASTNAME
HAVING
COUNT( CASE WHEN CT.TYPE = 'BOOK' THEN T.TRANSACTION_ID END )
> COUNT( CASE WHEN CT.TYPE = 'DVD' THEN T.TRANSACTION_ID END )
ORDER BY
C.CUSTOMER_FIRSTNAME
, C.CUSTOMER_LASTNAME
;
You can use catalog_item table twice( think of as seperate tables for books and dvds ), and compare by HAVING clause as :
SELECT C.CUSTOMER_FIRSTNAME, C.CUSTOMER_LASTNAME,
COUNT(CT1.CATALOG_ITEM_ID) as "Book Checkout",
COUNT(CT2.CATALOG_ITEM_ID) as "DVD Checkout"
FROM customer C
INNER JOIN library_card LC ON C.CUSTOMER_ID = LC.CUSTOMER_ID
INNER JOIN transaction T ON LC.LIBRARY_CARD_ID = T.LIBRARY_CARD_ID
INNER JOIN physical_item P ON T.PHYSICAL_ITEM_ID = P.PHYSICAL_ITEM_ID
LEFT JOIN catalog_item CT1 ON P.CATALOG_ITEM_ID = CT1.CATALOG_ITEM_ID AND CT1.TYPE = 'BOOK'
LEFT JOIN catalog_item CT2 ON P.CATALOG_ITEM_ID = CT2.CATALOG_ITEM_ID AND CT1.TYPE = 'DVD'
GROUP BY C.CUSTOMER_FIRSTNAME, C.CUSTOMER_LASTNAME
HAVING COUNT(CT1.CATALOG_ITEM_ID) > COUNT(CT2.CATALOG_ITEM_ID)
ORDER BY C.CUSTOMER_FIRSTNAME, C.CUSTOMER_LASTNAME;
CUSTOMER_FIRSTNAME CUSTOMER_LASTNAME Book Checkout DVD Checkout
------------------ ----------------- ------------- -------------
Deena Pilgrim 3 1
Emile Cross 5 2
Please try to remove ,CT1.TYPE, CT2.TYPE on your group by clause.

How to get rid of duplicating data in every row?

SELECT distinct AD.ReferenceNumber, AD.ProjectTitle, Z.ZoneCode, C.CompanyName,SS.AssignedTo, ZG.ZoneGroupName,au.Amount
FROM ApplicationDetails AD
LEFT JOIN ApplicationFormsDetails AS b ON (AD.referencenumber = b.referencenumber)
LEFT JOIN ScheduleSummaries AS SS ON (AD.ReferenceNumber = SS.ReferenceNo)
INNER JOIN AppTypes as at on ss.ItemCode = at.Category
INNER JOIN Companies AS C ON (AD.CompanyId = C.CompanyID)
INNER JOIN Zones Z ON (C.ZoneCode = Z.ZoneCode)
INNER JOIN ZoneGroups ZG ON (Z.ZoneGroup = ZG.ZoneGroupId)
LEFT JOIN AssessmentUsedItems au on ah.AssessmentHeaderId = au.HeaderId
WHERE AD.ApplicationDate BETWEEN '2017-10-01' AND '2017-10-31' AND ZG.ZoneGroupCode = 'HO' and ah.referencenumber = 'N-101317-A1-02'
GROUP BY AD.ReferenceNumber, AD.ProjectTitle, Z.ZoneCode, C.CompanyName,SS.AssignedTo, ZG.ZoneGroupName,au.Amount--, ah.ApplicationForm,au.Amount
The output of this query is its duplicating the amount for every AssignTO.
Output :
Maybe you want to try using SUM(ISNULL(au.amount, 0)) AS amount instead of au.amount and remove au.amount from the GROUP BY as well...
Try this query:
SELECT AD.ReferenceNumber,
AD.ProjectTitle,
Z.ZoneCode,
C.CompanyName,
SS.AssignedTo,
ZG.ZoneGroupName,
SUM(COALESCE(au.Amount,0)) AS Amount
FROM ApplicationDetails AD
LEFT JOIN ApplicationFormsDetails AS b
ON (AD.referencenumber = b.referencenumber)
LEFT JOIN ScheduleSummaries AS SS
ON (AD.ReferenceNumber = SS.ReferenceNo)
INNER JOIN AppTypes AS at
ON ss.ItemCode = at.Category
INNER JOIN Companies AS C
ON (AD.CompanyId = C.CompanyID)
INNER JOIN Zones Z
ON (C.ZoneCode = Z.ZoneCode)
INNER JOIN ZoneGroups ZG
ON (Z.ZoneGroup = ZG.ZoneGroupId)
LEFT JOIN AssessmentUsedItems au
ON ah.AssessmentHeaderId = au.HeaderId
WHERE AD.ApplicationDate BETWEEN '2017-10-01' AND '2017-10-31'
AND ZG.ZoneGroupCode = 'HO'
AND ah.referencenumber = 'N-101317-A1-02'
GROUP BY
AD.ReferenceNumber,
AD.ProjectTitle,
Z.ZoneCode,
C.CompanyName,
SS.AssignedTo,
ZG.ZoneGroupName

Long query mistake

I've just written a query here at work but I am getting "ORA-00920: invalid relational operator" when running it and I can't seem to find my mistake.
So here goes:
SELECT
D.DEPARTURE_NO,
D.DEPARTURE_DATE,
I.ITEM_GROUP_ID,
L.LUID,
OA.ADDRESS1,
OA.ADDRESS2,
OA.CITY,
OA.COUNTRY_CODE,
OA.NAME,
OA.POSTAL_CODE,
OA.RECEIVER_ID,
OC.COUNTRY_NAME,
OL.ORDER_LINE_NO,
O.INTERNAL_ORDER_ID,
O.RECEIVER_ORDER_ID,
O.STORER_ID,
O.STORER_ORDER_ID,
PL.BIN_LOCATION_ID,
PLL.PICK_STATUS,
PLL.PICKLIST_LINE_NO,
S.SHIPMENT_ID,
SH.NAME,
SH.SHIPPER_ID,
SS.SHIPPER_SERVICES_ID,
ST.NAME,
SA.ADDRESS_TYPE,
SA.ADDRESS1,
SA.ADDRESS2,
SA.ADDRESS3,
SA.CITY,
SA.POSTAL_CODE,
SC.COUNTRY_NAME,
VOPI.PARENT_INTERNAL_ORDER_ID
FROM
ORDERS O
INNER JOIN VY_ORDER_PARENT_ID VOPI ON VOPI.INTERNAL_ORDER_ID = O.INTERNAL_ORDER_ID
INNER JOIN VY_ORDER_PARENT_ID VOPI ON VOPI.INTERNAL_ORDER_ID = OA.INTERNAL_ORDER_ID
INNER JOIN ORDER_ADDRESS OA ON OA.INTERNAL_ORDER_ID = O.INTERNAL_ORDER_ID
INNER JOIN SHIPMENT S ON S.SHIPMENT_ID = O.SHIPMENT_ID
INNER JOIN SHIPPER_SERVICES SS ON SS.SHIPPER_SERVICES_NO = O.SHIPPER_SERVICES_NO
INNER JOIN STORER ST ON ST.STORER_ID = O.STORER_ID
INNER JOIN ORDER_LINE OL ON OL.INTERNAL_ORDER_ID = O.INTERNAL_ORDER_ID
INNER JOIN SHIPPER SH ON SH.SHIPPER_ID = O.SHIPPER_ID
INNER JOIN ORDER_COUNTRY OC ON OC.COUNTRY_CODE = OA.COUNTRY_CODE
INNER JOIN STORER_COUNTRY SC ON SC.COUNTRY_CODE OA.COUNTRY_CODE
INNER JOIN STORER_ADDRESS SA ON SA.COUNTRY_CODE = SC.STORER_ADDRESS
INNER JOIN STORER ST ON ST.STORER_ID = SA.STORER_ID
INNER JOIN DEPARTURE D ON D.ACTIVE_TRANSPORT_COUNTRY = SC.COUNTRY_CODE
INNER JOIN DEPARTURE D ON D.DEPARTURE_NO = S.DEPARTURE_NO
INNER JOIN ITEM I ON I.COUNTRY_CODE = SC.COUNTRY_CODE
INNER JOIN SHIPPER SH ON SH.SHIPPER_ID = S.SHIPPER_ID
INNER JOIN SHIPPER_SERVICES SS ON SS.SHIPPER_SERVICES_NO = S.SHIPPER_SERVICES_NO
INNER JOIN SHIPPER SH ON SH.SHIPPER_ID = SS.SHIPPER_ID
INNER JOIN IC_TRANSACTION ICT ON ICT.LUID_NO = L.LUID_NO
INNER JOIN PICKLIST_LINE PLL ON PLL.IC_TRANSACTION_NO = ICT.IC_TRANSACTION_NO
INNER JOIN LUID L ON L.STORER_ID = ST.STORER_ID
INNER JOIN ITEM I ON I.STORER_ID = ST.STORER_ID
INNER JOIN ITEM I ON I.ITEM_ID = OL.ITEM_ID AND I.STORER_ID = OL.ITEM_ID
INNER JOIN PICK_LOCATION PL ON PL.ITEM_ID = I.ITEM_ID AND PL.STORER_ID = I.ITEM_ID
INNER JOIN PICKLIST_LINE PLL ON PLL.EXPECTED_BIN_LOCATION_ID = PL.BIN_LOCATION_ID
INNER JOIN PICKLIST_LINE PLL ON PLL.EXPECTED_BUILDING_ID = PL.BUILDING_ID
INNER JOIN ORDER_LINE OL ON OL.INTERNAL_ORDER_ID = PLL.INTERNAL_ORDER_ID AND OL.ORDER_LINE_NO = PLL.ORDER_LINE_NO
WHERE S.SHIPMENT_ID = '2000518517'
Obviously you can't know the exact column names but I've gone through them multiple times and can't find any spelling errors.
Any other errors
INNER JOIN STORER_COUNTRY SC ON SC.COUNTRY_CODE OA.COUNTRY_CODE
should be
INNER JOIN STORER_COUNTRY SC ON SC.COUNTRY_CODE = OA.COUNTRY_CODE
and it looks like
INNER JOIN ORDER_LINE OL ON OL.INTERNAL_ORDER_ID = PLL.INTERNAL_ORDER_ID AND OL.ORDER_LINE NO = PLL.ORDER_LINE_NO
should be ( thanks to LONG )
INNER JOIN ORDER_LINE OL ON OL.INTERNAL_ORDER_ID = PLL.INTERNAL_ORDER_ID AND OL.ORDER_LINE_NO = PLL.ORDER_LINE_NO

How to retrieve count of records in SELECT statement

I am trying to retrieve the right count of records to mitigate an issue I am having. The below query returns 327 records from my database:
SELECT DISTINCT COUNT(at.someid) AS CountOfStudentsInTable FROM tblJobSkillAssessment AS at
INNER JOIN tblJobSkills j ON j.jobskillid = at.skillid
LEFT JOIN tblStudentPersonal sp ON sp.someid2 = at.someid
INNER JOIN tblStudentSchool ss ON ss.monsterid = at.someid
INNER JOIN tblSchools s ON s.schoolid = ss.schoolid
INNER JOIN tblSchoolDistricts sd ON sd.schoolid = s.schoolid
INNER JOIN tblDistricts d ON d.districtid = sd.districtid
INNER JOIN tblCountySchools cs ON cs.schoolid = s.schoolid
INNER JOIN tblCounties cty ON cty.countyid = cs.countyid
INNER JOIN tblRegionUserRegionGroups rurg ON rurg.districtid = d.districtid
INNER JOIN tblGroups g ON g.groupid = rurg.groupid
WHERE ss.graduationyear IN (SELECT Items FROM FN_Split(#gradyears, ',')) AND sp.optin = 'Yes' AND g.groupname = #groupname
Where I run into trouble is trying to reconcile that with the below query. One is for showing just a count of all the particular students the other is showing pertinent information for a set of students as needed but the total needs to be the same and it is not. The below query return 333 students - the reason is because the school the student goes to is in two separate counties and it counts that student twice. I can't figure out how to fix this.
SELECT DISTINCT #TableName AS TableName, d.district AS LocationName, cty.county AS County, COUNT(DISTINCT cc.monsterid) AS CountOfStudents, d.IRN AS IRN FROM tblJobSkillAssessment AS cc
INNER JOIN tblJobSkills AS c ON c.jobskillid = cc.skillid
INNER JOIN tblStudentPersonal sp ON sp.monsterid = cc.monsterid
INNER JOIN tblStudentSchool ss ON ss.monsterid = cc.monsterid
INNER JOIN tblSchools s ON s.schoolid = ss.schoolid
INNER JOIN tblSchoolDistricts sd ON sd.schoolid = s.schoolid
INNER JOIN tblDistricts d ON d.districtid = sd.districtid
INNER JOIN tblCountySchools cs ON cs.schoolid = s.schoolid
INNER JOIN tblCounties cty ON cty.countyid = cs.countyid
INNER JOIN tblRegionUserRegionGroups rurg ON rurg.districtid = d.districtid
INNER JOIN tblGroups g ON g.groupid = rurg.groupid
WHERE ss.graduationyear IN (SELECT Items FROM FN_Split(#gradyears, ',')) AND sp.optin = 'Yes' AND g.groupname = #groupname
GROUP BY cty.county, d.IRN, d.district
ORDER BY LocationName ASC
If you just want the count, then perhaps count(distinct) will solve the problem:
select count(distinct at.someid)
I don't see what at.someid refers to, so perhaps:
select count(distinct cc.monsterid)

Left Join gives no result

These are the two tables.
tbl_Invoice
tbl_Payment
What I want is Pending Invoices by a particular Client.
Existing Query is as below:
Select * from tbl_Invoice I
left join tbl_payment P on I.client_id = P.client_id
left join tbl_client C on I.client_id = C.client_id
where I.invoice_Id not in (P.invoice_Id)
and I.client_id = 8
But it gives blank result becuase the Payment table is blank.
You need to move condition from WHERE to ON :
Select * from tbl_Invoice I
left join tbl_payment P on (I.client_id = P.client_id
AND p.invoice_id <> I.invoice_Id)
left join tbl_client C on I.client_id = C.client_id
WHERE I.client_id = 5