ORDER BY clause error - sql-server

Hey guys I am getting this exception when trying to run the query
Column restaurantData.restaurantId is invalid in the select list
because it is not contained in either an aggregate function or the
GROUP BY clause.
Query:
SELECT
T1.restaurantId AS ID,
COUNT(T2.post_id) AS favCount
FROM
restaurantData AS T1
INNER JOIN
favoriteData AS T2 ON T1.restaurantId = T2.post_id
ORDER BY
favCount DESC, ID DESC
It says that I have to add all select columns which are not aggregated in ORDER BY clause, which I already did for restaurantID. But its still giving me error.

You are missing GROUP BY T1.restaurantId in the query.
SELECT T1.restaurantId AS ID,
COUNT(T2.post_id) AS favCount
FROM restaurantData AS T1
INNER JOIN favoriteData AS T2
ON T1.restaurantId = T2.post_id
GROUP BY T1.restaurantId
ORDER BY favCount DESC,
ID DESC
If you have no GROUP BY clause at all then this gives you an aggregate of the whole source table (in which case inclusion of restaurantId in the select list is invalid without wrapping that in an aggregate) rather than broken into groups by restaurant as you clearly desire.

You're using an aggregate function (COUNT), so you have to use a GROUP BY clause as well:
SELECT
T1.restaurantId AS ID,
COUNT(T2.post_id) AS favCount
FROM
restaurantData AS T1
INNER JOIN
favoriteData AS T2 ON T1.restaurantId = T2.post_id
GROUP BY
T1.restaurantID
ORDER BY
favCount DESC, ID DESC
Basically, with your query, you want to count the rows found - and you want the result grouped by each restaurantId - so that's what the GROUP BY clause expresses.

Related

Student, Department Order by both with condition

I am stuck in a query, my query is as follow:
SELECT department_name AS 'Department Name', COUNT(*) AS 'No of Employees' FROM departments INNER JOIN employees ON employees.department_id = departments.department_id GROUP BY departments.department_id, department_name
ORDER BY COUNT(*) DESC;
this query is giving me results as in below attachment
What i want now is to sort the departments alphabetically if two or more department have same number of students. e.g "Purchasing" and "Finance" should be sort alphabetically.
You can try this query in the following link:
Check your query here
This is simple. You can order by your result set by multiple columns as follows:
SELECT department_name AS 'Department Name', COUNT(*) AS 'No of Employees'
FROM departments INNER JOIN employees ON
employees.department_id = departments.department_id
GROUP BY departments.department_id, department_name
ORDER BY COUNT(*) DESC, department_name Asc;
The following thread is a good read
SQL Multiple Column Ordering
Hope this helps :)
Is this what you are looking for.?
SELECT department_name AS 'Department Name', COUNT(*) AS 'No of Employees'
FROM departments INNER JOIN employees ON employees.department_id = departments.department_id GROUP BY departments.department_id, department_name
ORDER BY department_name,COUNT(*) DESC;

Keeping the results with GROUP BY

I connect four tables, but if I do a GROUP BY with a propertie of the fourth table, I get different results. This is the Query:
There are basically two options:
JOIN back to original table using nested query.
SELECT TA.col1, AggrFunc(col2) AS col2,
(SELECT col3 -- TOP 1? MAX? It must be single row
FROM table1 AS TB
JOIN TA ON TA. = TB. -- INNER JOIN? LEFT OUTER JOIN?
FROM table1 AS TB JOIN table2 JOIN table3
GROUP BY TA.col1;
Or use a CTE. You have more control on how many rows of extra columns to return
WITH CTE AS
(
SELECT col1, AggrFunc(col2) AS col2
FROM ... JOINs
GROUP BY col1
)
SELECT CTE.*, table1.col3
FROM CTE
JOIN table1 --INNER JOIN? LEFT OUTER JOIN?
Use window function if possible
SELECT col1, AggrFunc(col2) OVER (PARTITION BY col1) AS col2, extra_col3
FROM ...JOINs...
then you can put above query a CTE or FROM clause to further filtering or grouping.
SELECT
FROM (query above)
WHERE ...
GROUP BY ...
The question is same: How do you get single extra_col3(SKU.[Reorder Cycle] in your case) row? How do you pick up one record when there are multiple matches to your grouped data.
Oke, this was doing the job(oke, I made a pivot of it):

Convert T-SQL Cross Apply to Oracle

I'm looking to convert this SQL Server (T-SQL) query that uses a cross apply to Oracle 11g. Oracle does not support Cross Apply until 12g, so I have to find a work-around. The idea behind the query is for each Tab.Name that = 'Foobar', I need find the previous row's name with the same ID ordered by Tab.Date. (This table contains multiple rows for 1 ID with different Name and Date).
Here is the T-SQL code:
SELECT DISTINCT t1.ID
t1.Name,
t1.Date,
t2.Date as 'PreviousDate',
t2.Name as 'PreviousName'
FROM Tab t1
OUTER apply (SELECT TOP 1 t2.Date,
t2.Name
FROM Tab t2
WHERE t1.Id = t2.Id
ORDER BY t2.Date DESC) t2
WHERE t1.Name = 'Foobar' )
Technically, I was able to recreate this same functionality in Oracle using LEFT JOIN and LAG() function:
SELECT DISTINCT t1.ID
t1.Name,
t1.Date,
t2.PreviousDate as PreviousDate,
t2.PreviousName as PreviousName
FROM Tab t1
LEFT JOIN (
SELECT ID,
LAG(Name) OVER (PARTITION BY ID ORDER BY PreviousDate) as PreviousName,
LAG(Date) OVER (PARTITION BY ID ORDER BY PreviousDate) as PreviousDate
FROM Tab) t2 ON t2.ID = t1.ID
WHERE t1.Name = 'Foobar'
The issue is the order it executes the Oracle query. It will pull back ALL rows from Tab, order them (because of the LAG function), then it will filter them down using the ON statement when it joins it to the main query. That table has millions of records, so doing that for EACH ID is not feasible. Basically, I want to change the order of operations in the sub-query to just pull back rows for a single ID, sort those rows to find the previous, and join that. Any ideas on how to tweak it?
TL;DR
SQL Server: filters, orders, joins
Oracle: orders, filters, joins
You can look for the latest row per (id) group with row_number():
select *
from tab t1
left join
(
select row_number() over (
partition by id
order by Date desc) as rn
, *
from t2
) t2
on t1.id = t2.id
and t2.rn = 1 -- Latest row per id

Small ms Sql query to get the max of an id with some criteria

I want sql query to get the above result. The result is the maximum Id in TableA whose s_id in TableB has Stat=true i.e. 1.
The following does not do what I want:
select i.category_id,i.image_id,i.image_original,i.image_title,i.photographer
from images i
inner join schedule s
on i.scheduleid=s.scheduleid
and s.status='live'
where image_id=(select max(image_id) from images)
Use TOP to retrieve only 1 row
Use ORDER BY to control the sorting, so you get the single row you want
SELECT TOP(1) a.id, a.[image], a.s_id, b.stat, b.[desc]
FROM TableA a
JOIN TableB b on a.s_id = b.s_id
WHERE b.stat = 1
ORDER BY A.ID DESC
An SQLFiddle showing this.

Choose an aggregate function for Group BY in SQL Server

I have a query like this:
Select Count(*) as TotalCount, Object2_ID, Object_ID, Object_Description
from Table1
inner join table2 on...
Group BY Object2_ID, Object_ID
I can't run this query because the column Object_Description isn't in GROUP BY or under aggregate function. Object_Description is a text column. I need any value of Object_Description. Now I use MAX(Object_Description) because it gives me right results, because Object_Description is the same for each group.
I can use MAX() or MIN() etc. - I will get right results in my query.
The question is - what is the most sufficient way to do this ?
I think that MAX() or MIN() produces small overheads.
You can get Object Description later, after calculation quantity (assumed that description in in table1 and you need get count from Table2):
SELECT Object_Id, Object_Description, Qty
FROM
(
SELECT Object_Id, Count(*) Qty
FROM Table2
GROUP BY Object_Id
) t
JOIN Table1 t2 on t2.Object_Id = t.Object_Id

Resources