SQL query error about movie.title is invalid - sql

SELECT TOP(100) M.title, count(WH.movie_id)
FROM Movie AS M
inner join WatchHistory AS WH ON M.movie_id = WH.movie_id
GROUP BY WH.movie_id, M.title, count(WH.movie_id)
ORDER BY count(WH.movie_id) ASC;
BlockquoteColumn 'Movie.title' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
My assignment is to do the following query:
Show 100 films that have gone so far
were looked at. This also means 0 times [film title, number of times viewed].
Make a View for this information requirement.
It gives the error above

There are plenty of issues:
count(WH.movie_id) removed from a GROUP BY
Added alias [CountViews]
Alias used in ORDER BY instead of aggregate
Fixed SQL:
SELECT TOP(100) M.title, count(WH.movie_id) as [CountViews]
FROM Movie AS M
inner join WatchHistory AS WH ON M.movie_id = WH.movie_id
GROUP BY M.title
ORDER BY [CountViews] ASC;

You should only group by M.title. If you intend to group rows, decide which columns will be grouped. Remember that only columns in the GROUP BY clause, in addition to aggregate functions such as COUNT, may ultimately be included in the SELECT clause. Grouped aggregate functions operate on sets of rows defined in a GROUP BY clause and return a summarized result. Examples include SUM, MIN, MAX COUNT, and AVG. In the absence of a GROUP BY clause, all rows are considered one set; aggregation is performed on all of them.

Related

How to fix "Column 'ColumnName' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause."

Needing to fix the mentioned code error for my SQL query
Error: "Column 'ColumnName' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause."
I am under the impression that an aggregate function needs to be implemented, however I do not understand how.
My query:
SELECT
TransactionID,
InvoiceSum.TransNum,
PosTransaction.OrderID,
PosTransaction.PatientID,
Patient.ID,
Patient.MedicalRecordNum,
PosTransaction.OfficeNum AS Pos_OfficeNum,
Patient.ExamOffice,
TransactionDate,
Patient.FirstName,
Patient.LastName,
Patient.BirthDate,
Patient.Sex,
Item.ItemNum,
Item.ItemName
FROM PosTransaction Inner Join Patient ON PosTransaction.PatientID =
Patient.ID
Inner Join InvoiceSum ON PosTransaction.TransactionID =
InvoiceSum.TransNum
Inner Join InvoiceDet ON InvoiceSum.InvoiceID = InvoiceDet.InvoiceID
Inner Join Item ON InvoiceDet.ItemID = Item.ID
GROUP BY Patient.ID
ORDER BY TransactionDate
I am expecting to see duplicate customer names to be removed from the output once properly I understand how to use GROUP BY.
If you only group by patient.ID, what will happen to other columns?
(The server does not know what it should do, so it raises an error)
The server does not know what you want to do with the other columns.
(So You need the aggregate function(s) to tell the SQL server)
Simple example:
ID|salary
01|1000
01|2000
01|3000
If I only group by id here:
select id, salary
from sample
group by id
How do you want to calculate salary? Sum, max, min?
So you need the aggregate function:
select id, sum(salary)
from sample
group by id
Comment below if you have any questions.

Counting subquery results SQL Oracle

So the code I have is trying to count the number of ratings given to a movie per state. That's all easy done. I also need to count the number of ratings given to award winning movies, per state.
SELECT DISTINCT ad.state "State",
COUNT(r.ratingid) OVER (PARTITION BY ad.state) "Number of Ratings",
COUNT(
SELECT DISTINCT r.ratingid
FROM netflix.ratings100 r JOIN netflix.movies_awards a
ON r.movieid = a.movieid
JOIN netflix.addresses ad
ON ad.custid = r.custid
WHERE a.awardid IS NOT NULL
) OVER (PARTITION BY ad.state) "Number of Award Winning Movies Rated"
FROM netflix.addresses ad JOIN netflix.ratings100 r
ON ad.custid = r.custid
JOIN netflix.movies_awards a
ON r.movieid = a.movieid
GROUP BY "State"
The second count statement should be counting the number of ratings made where the awardID is not null. That subquery alone works, and returns distinct ratingIDs, but the thing as a whole does not work. I get ORA-00936: missing expression. Solutions?
You haven't got brackets around the subquery - you have the brackets to indicate the count, but you need an extra set to indicate that it's a subquery.
E.g;
count( (select ....) ) over ...
Moreover, you're reusing the aliases from your outer query in your inner query, plus there's nothing to correlate the subquery to your outer query, so I don't think you're going to get the results you're after.
Additionally, you've labelled a column with an identifier that's over 30 characters, so unless you're on 12.2 with the extended identifiers set, you're going to get ORA-00972: identifier is too long.
Finally, I don't think you need that subquery at all; I think you can just use a conditional count, e.g.:
SELECT DISTINCT ad.state "State",
COUNT(r.ratingid) over(PARTITION BY ad.state) "Number of Ratings",
COUNT(DISTINCT CASE WHEN a.awardid IS NOT NULL THEN r.ratingid END) over(PARTITION BY ad.state) "Num Award Winning Movies Rated"
FROM netflix.addresses ad
JOIN netflix.ratings100 r
ON ad.custid = r.custid
JOIN netflix.movies_awards a
ON r.movieid = a.movieid
GROUP BY "State";
You may not even need that distinct; it depends on your data. Hopefully you can play around with that and get it to work for your requirements.
That seems like a complicated query. This should be an aggregation query . . . with a correlated subquery:
SELECT ad.state, COUNT(DISTINCT r.ratingId) as num_rated,
COUNT(DISTINCT CASE WHEN a.awardId IS NOT NULL THEN r.ratingid END) as num_rated_with_award
FROM netflix.addresses ad JOIN
netflix.ratings100 r
ON ad.custid = r.custid LEFT JOIN
netflix.movies_awards a
ON r.movieid = a.movieid
GROUP BY ad.state;
Notes:
There is no reason to give a column an alias equivalent to its original name. So, as "State" is unnecessary, unless you really care about capitalization.
A movie could have more than one award, so to get the number of ratings, use count(distinct).
SELECT DISTINCT is almost never appropriate with GROUP BY.
The query has no need of window functions.

GROUP BY not working in left join query

I m trying to use group by clause in left join sql query and it is not working.
Please help me out, thanks in advance.
SELECT Cust_Mst_Det.Cust_Hd_Code,
Cust_Mst_Det.First_Name,
SL_HEAD20152016.vouch_date AS invoice_2,
SL_HEAD20142015.vouch_date AS invoice_1,
Cust_Mst_Hd.EMail
FROM Cust_Mst_Det
LEFT JOIN SL_HEAD20142015 ON Cust_Mst_Det.Cust_Hd_Code=SL_HEAD20142015.Member_Code
LEFT JOIN SL_HEAD20152016 ON Cust_Mst_Det.Cust_Hd_Code=SL_HEAD20152016.Member_Code
LEFT JOIN Cust_Mst_Hd ON Cust_Mst_Det.Cust_Hd_Code=Cust_Mst_Hd.Cust_Hd_Code
WHERE cust_mst_det.first_name!='NIL'
GROUP BY Cust_Mst_Det.Cust_Hd_Code
ORDER BY SL_HEAD20152016.vouch_date DESC,
SL_HEAD20142015.vouch_date
I'm not sure which DBMS you are using, but on an Oracle your query will not work at all.
First issue: The GROUP BY statement is used in conjunction with the aggregate functions to group the result-set by one or more columns. You do not have any aggregating function in your SELECT statement (count, max, etc.)
Second issue: you must specify all columns from SELECT statement in your GROUP BY statement (excluding columns that represents results of aggregation).
As I said I don't know which DB is used by you, but those two points should be applicable for the most of SQL standards.
It appears that it is impossible to use an ORDER BY on a GROUP BY summarisation. My fundamental logic is flawed. I will need to run the following subquery.
ex :
SELECT p.*, pp.price
FROM products p
LEFT JOIN ( SELECT price FROM product_price ORDER BY date_updated DESC ) pp
ON p.product_id = pp.product_id GROUP BY p.product_id;
This will take a performance hit but as it is the same subquery for each row it shouldn't be too bad.

how to use count with where clause in join query

SELECT
DEPTMST.DEPTID,
DEPTMST.DEPTNAME,
DEPTMST.CREATEDT,
COUNT(USRMST.UID)
FROM DEPTMASTER DEPTMST
INNER JOIN USERMASTER USRMST ON USRMST.DEPTID=DEPTMST.DEPTID
WHERE DEPTMST.CUSTID=1000 AND DEPTMST.STATUS='ACT
I have tried several combination but I keep getting error
Column 'DEPTMASTER.DeptID' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause
I also add group by but it's not working
WHen using count like that you need to group on the selected columns,
ie.
SELECT
DEPTMST.DEPTID,
DEPTMST.DEPTNAME,
DEPTMST.CREATEDT,
COUNT(USRMST.UID)
FROM DEPTMASTER DEPTMST
INNER JOIN USERMASTER USRMST ON USRMST.DEPTID=DEPTMST.DEPTID
WHERE DEPTMST.CUSTID=1000 AND DEPTMST.STATUS='ACT'
GROUP BY DEPTMST.DEPTID,
DEPTMST.DEPTNAME,
DEPTMST.CREATEDT
you miss group by
SELECT DEPTMST.DEPTID,
DEPTMST.DEPTNAME,
DEPTMST.CREATEDT,
COUNT(USRMST.UID)
FROM DEPTMASTER DEPTMST
INNER JOIN USERMASTER USRMST ON USRMST.DEPTID=DEPTMST.DEPTID
WHERE DEPTMST.CUSTID=1000 AND DEPTMST.STATUS='ACT
group by DEPTMST.DEPTID,
DEPTMST.DEPTNAME,
DEPTMST.CREATEDT
All aggregate functions like averaging, counting,sum needs to be used along with a group by function. If you dont use a group by clause, you are performing the function on all the rows of the table.
Eg.
Select count(*) from table;
This returns the count of all the rows in the table.
Select count(*) from table group by name
This will first group the table data based on name and then return the count of each of these groups.
So in your case, if you want the countof USRMST.UID, group it by all the other columns in the select list.

Postgres aggregate problem

I'm not sure why this won't work:
SELECT u.id, u.tag, u.unit_type, Count(p.id) AS num_points
FROM ot2.unit u
INNER JOIN ot2.point p on p.unit_id = u.id
GROUP BY u.id
HAVING Count(p.id) > 800;
ERROR: column "u.tag" must appear in the GROUP BY clause or be used in an aggregate function
SQL state: 42803
I have already provided a column for group by.
Just what the error says. u.tag is not in the group by and you aren't telling how to aggregate the different u.tag values to a single one.
More concrete you have 2 options:
Add u.tag in the group by clause (and u.unit_type as well)
use an aggregate function on those 2 fields (min, max, sum, avg, ....)