ORA-00907: missing right parenthesis - sql

I'm getting the error " ORA-00907: missing right parenthesis"
but I've checked and all the parenthesis are there, so I'm stumped.
My query is
SELECT
SUM(score) as score,
facebook_id,
firstname,
lastname,
dense_rank(score)
WITHIN GROUP ( ORDER BY score ) as rank_db
FROM
(
SELECT DISTINCT *
FROM
(
SELECT *
FROM fanta_score
ORDER BY score desc
) as f
GROUP BY
facebook_id, game_id
) as g
GROUP BY facebook_id
ORDER BY score DESC, created_at
LIMIT 50
I'm by no means an Oracle expert, but I have to use it due the hosting environment its has to be in.

LIMIT command isn't recognized in Oracle. And should use ROWNUM instead of Limit.
SELECT
SUM(score) as score,
facebook_id,
firstname,
lastname,
dense_rank(score)
WITHIN GROUP ( ORDER BY score ) as rank_db
FROM
(
SELECT DISTINCT *
FROM
(
SELECT *
FROM fanta_score
ORDER BY score desc
) as f
GROUP BY
facebook_id, game_id
) as g
WHERE ROWNUM = 50
GROUP BY facebook_id
ORDER BY score DESC, created_at

Related

Group by two columns, take sum, then max

There are three columns: Id (char), Name (char), and Score (int).
First, we group by Id and Name and add Score for each group. Let us call the added score total_score.
Then, we group by Name and take only the maximum of total_score and its corresponding Id and Name. I've got everything else but I'm having a hard time figuring out how to get the Id. The error I get is
Column 'Id' is invalid in the select list because
it is not contained in either an aggregate function or the GROUP BY
clause.
WITH Tmp AS
(SELECT Id,
Name,
SUM(Score) AS total_score
FROM Mytable
GROUP BY Id,
Name)
SELECT Name, -- Id,
MAX(total_score) AS max_score
FROM Tmp
GROUP BY Name
ORDER BY max_score DESC
just add row_number() partition by Name to your query and get the 1st row (order by total_score descending)
select *
from
(
-- your existing `total_score` query
SELECT Id, Name,
SUM(Score) AS total_score,
r = row_number() over (partition by Name order by SUM(Score) desc)
FROM Mytable
GROUP BY Id, Name
) d
where r = 1
WITH Tmp AS
(SELECT Id,
Name,
SUM(Score) AS total_score
FROM Mytable
GROUP BY Id,
Name)
SELECT Name, Id,
MAX(total_score) AS max_score
FROM Tmp
GROUP BY Name,id
ORDER BY max_score DESC
Try this. Hope this will help.
WITH Tmp AS
(
SELECT Id,
Name,
SUM(Score) AS total_score
FROM Mytable
GROUP BY Id,
NAME
)
SELECT Name, Id,
MAX(total_score) AS max_score
FROM Tmp
GROUP BY Name,id
ORDER BY max_score DESC
Note:- If we are using aggregate function then we have to use other column as Group By....
In your case you are using SUM(Score) as aggregate function then we to use other column as Group by ...
I am not sure about performance of below query but we can use window functions to get maximum value from data partition.
SELECT
Id,
Name,
SUM(Score) AS total_score,
MAX(SUM(Score)) OVER(Partition by Name) AS max_score
FROM Mytable
GROUP BY Id, Name;
Tested -
declare #Mytable table (id int, name varchar(10), score int);
insert into #Mytable values
(1,'abc', 100),
(2,'abc', 200),
(3,'def', 300),
(3,'def', 400),
(4,'pqr', 500);
Output -
Id Name total_score max_score
1 abc 100 200
2 abc 200 200
3 def 700 700
4 pqr 500 500
You can select DENSE_RANK() with total_score column and then select records with Rank = 1. This will work for those also when there are multiple Name which are having same total_score.
WITH Tmp AS
(SELECT Id,
Name,
SUM(Score) AS total_score
FROM Mytable
GROUP BY Id, Name)
SELECT Id,
Name,
total_score AS max_score
FROM (SELECT Id,
Name,
total_score,
DENSE_RANK() OVER (PARTITION BY Name ORDER BY total_score DESC) AS Rank
FROM Tmp) AS Tmp2
WHERE Rank = 1
You can try this as well:
select id,name,max(total_score) over (partition by name) max_score from (
select id,name,sum(score) as total_score from YOURTABLE
group by id,name
) t

SQL Server 2008 merging the result of two queries

I am trying to merge the result of both the queries below using the UNION operator in SQL Server 2008 but got the following error
Incorrect syntax near the keyword 'union'.
My code:
SELECT TOP 1
CITY, LEN(CITY)
FROM
table1
ORDER BY
LEN (CITY), CITY ASC
UNION
SELECT TOP 1
CITY, LEN(CITY)
FROM
table1
ORDER BY
LEN (CITY) DESC, CITY ASC
Any comments would be appreciated.
Thanks
Here is the correct way to do it
Select * From
(
SELECT TOP 1
CITY, cityLen = LEN(CITY)
FROM
table1
ORDER BY
cityLen, CITY ASC
) a
UNION
Select * From
(
SELECT TOP 1
CITY, cityLen = LEN(CITY)
FROM
table1
ORDER BY
cityLen DESC, CITY ASC
) b
or using Row_Number window function
select * from
(
select *,
ROW_NUMBER() OVER(ORDER BY LEN (CITY) DESC, CITY ASC) as Drn,
ROW_NUMBER() OVER(ORDER BY LEN (CITY) ASC, CITY ASC) as Arn,
FROM table1
) a
where 1 in (Arn,Drn)
In this case, you can use Common table expression. Try this
;With cte
AS (
select * , ROW_NUMBER() OVER(ORDER BY LEN (CITY) DESC, CITY ASC) as rn
FROM table1
)
select * from cte where rn = 1
union
select * from cte where rn = 1
Remove the ASC order command in your first select statement. You can only order the result at the end of any query as ordering in the middle of a query (if allowed) would cause many problems in getting consistent results.
EDIT: I realized the table were the same, you need to use Union ALL, or as stated in other comments, the duplicates are taken out in a UNION.
SELECT TOP 1
CITY, LEN(CITY)
FROM
table1
UNION ALL
SELECT TOP 1
CITY, LEN(CITY)
FROM
table1
ORDER BY
LEN (CITY) DESC, CITY ASC

How to find the most repeat data in oracle?

I have a TRANSACTION table.
Columns are =
Personnel_id and Personnel_Name
I want to find the most repetitive data sorting.
How i can do it?
I have tried and I found, the most repetitive result but i can't show personnel_name.
Here is my query ;
SELECT PERSONNEL_ID,
COUNT(PERSONNEL_ID)
FROM KOMTAS.TRANSACTIONS
GROUP BY PERSONNEL_ID;
And this code gives an error ;
SELECT MAX(R),
PERSONNEL_ID
FROM ( SELECT PERSONNEL_ID,
COUNT(PERSONNEL_ID) R
FROM KOMTAS.TRANSACTIONS
GROUP BY PERSONNEL_ID
) ;
help please !
Add a second group by to the second query:
SELECT MAX(R),
PERSONNEL_ID
FROM ( SELECT PERSONNEL_ID,
COUNT(PERSONNEL_ID) R
FROM KOMTAS.TRANSACTIONS
GROUP BY PERSONNEL_ID )
GROUP BY PERSONNEL_ID;
I would suggest using rownum and a subquery:
SELECT t.*
FROM (SELECT PERSONNEL_ID, COUNT(PERSONNEL_ID) as cnt
FROM KOMTAS.TRANSACTIONS
GROUP BY PERSONNEL_ID
ORDER BY COUNT(PERSONNEL_ID) DESC
) t
WHERE rownum = 1;
Try This
SELECT MAX(cnt) AS c,
PersonId
FROM ( SELECT PersonId,
COUNT(PersonId) cnt
FROM TRANSACTIONS
GROUP BY PersonId )
GROUP BY PersonId
ORDER BY c DESC;
Check here SQLFiddle

sql query to find the duplicate records

what is the sql query to find the duplicate records and display in descending, based on the highest count and the id display the records.
for example:
getting the count can be done with
select title, count(title) as cnt from kmovies group by title order by cnt desc
and the result will be like
title cnt
ravi 10
prabhu 9
srinu 6
now what is the query to get the result like below:
ravi
ravi
ravi
...10 times
prabhu
prabhu..9 times
srinu
srinu...6 times
If your RDBMS supports the OVER clause...
SELECT
title
FROM
(
select
title, count(*) OVER (PARTITION BY title) as cnt
from
kmovies
) T
ORDER BY
cnt DESC
You can do it in a single query:
Select t.Id, t.title, z.dupCount
From yourtable T
Join
(select title, Count (*) dupCount
from yourtable
group By title
Having Count(*) > 1) z
On z.title = t.Title
order By dupCount Desc
This query uses the Group By and and Having clauses to allow you to select (locate and list out) for each duplicate record. The As clause is a convenience to refer to Quantity in the select and Order By clauses, but is not really part of getting you the duplicate rows.
Select
Title,
Count( Title ) As [Quantity]
From
Training
Group By
Title
Having
Count( Title ) > 1
Order By
Quantity desc
select distinct title, (
select count(title)
from kmovies as sub
where sub.title=kmovies.title) as cnt
from kmovies
group by title
order by cnt desc
You can't do it as a simple single query, but this would do:
select title
from kmovies
where title in (
select title
from kmovies
group by title
order by cnt desc
having count(title) > 1
)

Column is invalid error when using derived table

I'm using ROW_NUMBER() and a derived table to fetch data from the derived table result.
However, I get the error message telling me I don't have the appropriate columns in the GROUP BY clause.
Here's the error:
Column 'tblCompetition.objID' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause
What column am I missing? Or am I doing something else wrong? Find below the query that is not working, and the (more simple) query that is working.
SQL Server 2008.
Query that isn't working:
SELECT
objID,
objTypeID,
userID,
datAdded,
count,
sno
FROM
(
SELECT scc.objID,scc.objTypeID,scc.userID,scc.datAdded,
COUNT(sci.favID) as count,
ROW_NUMBER() OVER(PARTITION BY scc.userID ORDER BY scc.unqID DESC) as sno
FROM tblCompetition scc
LEFT JOIN tblFavourites sci
ON sci.favID = scc.objID
AND sci.datTimeStamp BETWEEN #datStart AND #datEnd
) as t
WHERE sno <= 2 AND objTypeID = #objTypeID
AND datAdded BETWEEN #datStart AND #datEnd
GROUP BY objID,objTypeID,userID,datAdded,count,sno
Simple query that is working:
SELECT objId,objTypeID,userId,datAdded FROM
(
SELECT objId,objTypeID,userId,datAdded,
ROW_NUMBER() OVER(PARTITION BY userId ORDER BY unqid DESC) as sno
FROM tblRdbCompetition
) as t
WHERE sno<=2 AND objtypeid=#objTypeID
AND datAdded BETWEEN #datStart AND #datEnd
Thank you!
you need the GROUP BY in your subquery since that's where the aggregate is:
SELECT
objID,
objTypeID,
userID,
datAdded,
count,
sno
FROM
(
SELECT scc.objID,scc.objTypeID,scc.userID,scc.datAdded,
COUNT(sci.favID) as count,
ROW_NUMBER() OVER(PARTITION BY scc.userID ORDER BY scc.unqID DESC) as sno
FROM tblCompetition scc
LEFT JOIN tblFavourites sci
ON sci.favID = scc.objID
AND sci.datTimeStamp BETWEEN #datStart AND #datEnd
GROUP BY scc.objID,scc.objTypeID,scc.userID,scc.datAdded) as t
WHERE sno <= 2 AND objTypeID = #objTypeID
AND datAdded BETWEEN #datStart AND #datEnd
You cannot have count in a group by clause. Infact the count is derived when you have other fields in group by. Remove count from your Group by.
In the innermost query you are using
COUNT(sci.favID) as count,
which is an aggregate, and you select other non-aggregating columns along with it.
I believe you wanted an analytic COUNT instead:
SELECT objID,
objTypeID,
userID,
datAdded,
count,
sno
FROM (
SELECT scc.objID,scc.objTypeID,scc.userID,scc.datAdded,
COUNT(sci.favID) OVER (PARTITION BY scc.userID ) AS count,
ROW_NUMBER() OVER (PARTITION BY scc.userID ORDER BY scc.unqID DESC) as sno
FROM tblCompetition scc
LEFT JOIN
tblFavourites sci
ON sci.favID = scc.objID
AND sci.datTimeStamp BETWEEN #datStart AND #datEnd
) as t
WHERE sno = 1
AND objTypeID = #objTypeID