Multiple table join query, with count in Oracle SQL - sql

I'm trying to count the number of inspections of each property in YR_Inspection table by counting the number of times the property number occurs in the table, i then need to display this next to the town the city the property is located in and the branch the property belongs to all in the same query. Here is the link to my ERD to try and give this question some context,
http://www.gliffy.com/pubdoc/4239520/L.png
this is the code so far, it works so far but as soon as i add YR_Branch.CITY i get,
ORA-00979: not a GROUP BY expression
SELECT YR_Property.PROPERTYNUM, COUNT(YR_Inspection.PROPERTYNUM) AS Number_of_inspections
FROM YR_Property
INNER JOIN YR_Inspection
ON YR_Property.PROPERTYNUM = YR_Inspection.PROPERTYNUM
JOIN YR_Branch
ON YR_Property.BRANCHNUM = YR_Branch.BRANCHNUM
GROUP BY YR_Property.PROPERTYNUM

To add the branch number and the city for the branch, add max values for each to the query - like so:
SELECT YR_Property.PROPERTYNUM,
COUNT(YR_Inspection.PROPERTYNUM) AS Number_of_inspections,
MAX(YR_Branch.BRANCHNUM) AS Branch_Number,
MAX(YR_Branch.CITY) AS Branch_City
FROM YR_Property
INNER JOIN YR_Inspection
ON YR_Property.PROPERTYNUM = YR_Inspection.PROPERTYNUM
JOIN YR_Branch
ON YR_Property.BRANCHNUM = YR_Branch.BRANCHNUM
GROUP BY YR_Property.PROPERTYNUM

Related

My question is about SQL, using a TOP function inside a sub-query in MS Access

Overall what I'm trying to achieve is a query that shows the most ordered item from a customer in a database. To achieve this I've tried making a query showing how many times a customer has ordered an item, and now I am trying to create a sub-query in it using TOP1 to discern the most bought items.
With the SQL from the first query (looking weird because I made it with the Access automatic creator):
SELECT
Customers.CustomerFirstName,
Customers.CustomerLastName,
Products.ProductName,
COUNT(SalesQuantity.ProductCode) AS CountOfProductCode
FROM (Employees
INNER JOIN (Customers
INNER JOIN Sales
ON Customers.CustomerCode = Sales.CustomerCode)
ON Employees.EmployeeCode = Sales.EmployeeCode)
INNER JOIN (Products
INNER JOIN SalesQuantity
ON Products.ProductCode = SalesQuantity.ProductCode)
ON Sales.SalesCode = SalesQuantity.SalesCode
GROUP BY
Customers.CustomerFirstName,
Customers.CustomerLastName,
Products.ProductName
ORDER BY
COUNT(SalesQuantity.ProductCode) DESC;
I have tried putting in a subquery after FROM line:
(SELECT TOP1 CountOfProduct(s)
FROM (.....)
ORDER by Count(SalesQuantity.ProductCode) DESC)
I'm just not sure what to put in for the "from"-every other tutorial has the data from an already created table, however this is from a query that is being made at the same time. Just messing around I've put "FROM" and then listed every table, as well as
FROM Count(SalesQuantity.ProductCode)
just because I've seen that in the order by from the other code, and assume that the query is discerning from this count. Both tries have ended with an error in the syntax of the "FROM" line.
I'm new to SQL so sorry if it's blatantly obvious, but any help would be greatly appreciated.
Thanks
As I understand, you want the most purchased product for each customer.
So, begin by building aggregate query that counts product purchases by customer (appears to be done in the posted image). Including customer ID in the query would simplify the next step which is to build another query with TOP N nested query.
Part of what complicates this is unique record identifier is lost because of aggregation. Have to use other fields from the aggregate query to provide unique identifier. Consider:
SELECT * FROM Query1 WHERE CustomerID & ProductName IN
(SELECT TOP 1 CustomerID & ProductName FROM Query1 AS Dupe
WHERE Dupe.CustomerID = Query1.CustomerID
ORDER BY Dupe.CustomerID, Dupe.CountOfProductCode DESC);
Overall what I'm trying to achieve is a query that shows the most ordered item from a customer in a database.
This answers your question. It does not modify your query which is only tangentially related.
SELECT s.CustomerCode, sq.ProductCode, SUM(sq.quantity) as qty
FROM Sales as s INNER JOIN
SalesQuantity as sq
ON s.SalesCode = sq.SalesCode
GROUP BY s.CustomerCode, sq.ProductCode;
To get the most ordered items, you can use this twice:
SELECT s.CustomerCode, sq.ProductCode, SUM(sq.quantity) as qty
FROM Sales as s INNER JOIN
SalesQuantity as sq
ON s.SalesCode = sq.SalesCode
GROUP BY s.CustomerCode, sq.ProductCode
HAVING sq.ProductCode IN (SELECT TOP 1 sq2.ProductCode
FROM Sales as s2 INNER JOIN
SalesQuantity as sq2
ON s2.SalesCode = sq2.SalesCode
WHERE s2.CustomerCode = s.CustomerCode
GROUP BY sq2.ProductCode
);
In almost any other database, this would be simpler, because you would be able to use window functions.

LEFT JOIN two tables with multiple AND conditions

I need help getting a sql statement correctly by joining two tables.
My goal is to return the number of purchases between certain purchase dates for given products where customer_id is null. The foreign key for table Purchases is prospect_id corresponding to id in Prospect
In separate SQL statements, I will have this:
SELECT COUNT (id) FROM Purchases
WHERE (purchasedate BETWEEN '5/1/18' AND '12/31/18')
AND (product = 'Scooter')
SELECT id
from Prospect
where customer_id is null
So, I am coming up with a query like this:
SELECT COUNT (id)
FROM Purchases
LEFT JOIN Prospect
ON Prospect.id = Purchases.prospect_id
AND (Purchases.purchasedate BETWEEN '5/1/18' AND '12/31/18')
AND Purchases.product = 'Scooter'
AND Prospect.customer_id is null;
but then I am getting ERROR: column reference "id" is ambiguous.
Use count(*):
SELECT COUNT(*)
FROM Purchases pu LEFT JOIN
Prospect pr
ON pr.id = pu.prospect_id AND
pr.customer_id is null
WHERE pu.purchasedate >= '2018-05-01' AND
pu.purchasedate < '2019-01-01' AND
pu.product = 'Scooter';
I made a few changes to the query.
First, the conditions on purchase are in the where clause rather than the on clause. Presumably, you actually want these to be filters.
Second, the dates use a proper format, YYYY-MM-DD.
I've also replaced the between with explicit comparisons. This means that the code works even when the "date" column has a time component.
Finally, I also introduced table aliases.
the reason for your error is that you did not define what table the "id" field you want to count is coming from.
SELECT
COUNT(PURCHASES.ID) AS PURCHASE_COUNT
FROM
Purchases
LEFT JOIN Prospect
ON Prospect.id = Purchases.prospect_id
AND (Purchases.purchasedate BETWEEN '5/1/18' AND '12/31/18')
AND Purchases.product = 'Scooter'
AND Prospect.customer_id is null;

Querying records that meet muliple criteria

Hi I’m trying to write a query and I’m struggling to figure out how to go about it.
I have a suppliers table and a supplier parts table I want to write a query that lists suppliers that have specified related Parts in the supplier parts table. If a supplier doesn’t have all specified related parts then they should not be listed.
At the moment I have written a very basic query that lists the supplier if they have a related supplier part that meets the criteria.
SELECT id ,name
FROM
efacdb.dbo.suppliers INNER JOIN [efacdb].[dbo].[spmatrix] ON
id = spmsupp
WHERE spmpart
IN ('ALUM_5083', 'ALUM_6082')
I only want to show the supplier if they have both parts related. Does anyone know how I could do this?
Use a subquery with counting distinct occurences:
select * from suppliers s
where 2 = (select count(distinct spmpart) from spmatrix
where id = spmsupp and spmpart in ('ALUM_5083', 'ALUM_6082'))
As a note, you can modify your query to get what you want, just by using an aggregation:
SELECT id, name
FROM efacdb.dbo.suppliers INNER JOIN
[efacdb].[dbo].[spmatrix]
ON id = spmsupp
WHERE spmpart IN ('ALUM_5083', 'ALUM_6082')
GROUP BY id, name
HAVING MIN(spmpart) <> MAX(spmpart);
If you know there are no duplicates, then having count(*) = 2 also solves the problem.

SQL Displaying data by joining 3 tables when data exits in 2 out of 3 table

May I know how many joins should I have if I want to list the stud number, stud name, and the total number of course each student applied for?
Since the appnCseNum = cseNum and studNum = appcnStudNum
STUDENT(studNum, studName, studDOB, studAddress)
COURSE(cseNum, cseStartDate, cseEndDate)
APPLICATION(appcnCseNum, appcnStudNum)
SELECT STUDENT.studNum, STUDENT.studName, COUNT(APPLICATION.appcnCseNum) AS coursenum
FROM STUDENT JOIN APPLICATION
ON STUDENT.studNum= APPLICATION.appcnCseNum;
Do I need to have another join for the COURSE in order retrieve the result? because the error i got was "not a single-group group function".
If i do not include the count, if works perfectly fine.
SELECT APPLICANT.appNum, APPLICANT.appName, APPLICATION.appcnPosNum
FROM APPLICANT JOIN APPLICATION
ON APPLICANT.appNum = APPLICATION.appcnAppNum;
--------------------------SOLVED--------------------
SELECT STUDENT.studNum, STUDENT.studName, COUNT(APPLICATION.appcnCseNum) AS coursenum
FROM STUDENT JOIN APPLICATION
ON STUDENT.studNum = APPLICATION.appcnStudNum
GROUP BY STUDENT.studName, STUDENT.studName;
No you'll not need another join to retrieve the result but however your query is wrong,try this
SELECT STUDENT.studNum, STUDENT.studName, COUNT(APPLICATION.appcnCseNum) AS coursenum
FROM STUDENT JOIN APPLICATION
ON STUDENT.studNum = APPLICATION.appcnStudNum
GROUP BY STUDENT.studName;

SQL like clause is not returning any results

I have following query, but it doesn't return any results for where clauses, even when there is row with that kind of name what is queried. If I remove where clause, then all records in Company table which have OfficeLocation table are returned. What is wrong in my query?
SELECT c.*
FROM [MyDb].[dbo].[Company] AS c
INNER JOIN [MyDb].[dbo].[CompanyOfficeLocation] AS col ON c.Id = col.CompanyId
INNER JOIN [MyDb].[dbo].[OfficeLocation] AS ol ON ol.Id = col.OfficeLocationId
WHERE ol.Name like '%Actual Name In This Table%';
Table structure :
Company
Id
etc ...
CompanyOfficeLocation
CompanyId
OfficeLocationId
OfficeLocation
Id
etc ...
Two things for a record to show up given your query:
The OfficeLocation you specified (given the ol.Name value) must have an Id value that is used by a record in the CompanyOfficeLocation table in its OfficeLocationId.
The CompanyOfficeLocation record that you got in #1 must have a CompanyId that exists in the Company table.
If any of those two criteria are not met, then no records will show up in your query result. The INNER JOIN is essentially an 'AND' clause. If a record could not be related to at least one INNER JOINed table, then that record will not show up at all.
If you want a record to show up despite not having any related records in the joined tables, you may want to consider using OUTER JOINs. A RIGHT JOIN in your case to be exact.
I do not find any mistake however I'd suggest you switch the columns after ON when joining to maintain standards.
Instead of - INNER JOIN [MyDb].[dbo].[OfficeLocation] AS ol ON ol.Id = col.OfficeLocationId
Do - INNER JOIN [MyDb].[dbo].[OfficeLocation] AS ol ON col.OfficeLocationId = ol.Id