Oracle SQL Sum missing right parenthesis - sql

I have an Oracle SQL that works on MySQL, but I get the "missing right parenthesis" when I run On Oracle.
I put it on sqlfiddle

Oracle does not have a shorthand way of using a CASE or if like MySQL. As a result you will have to use a CASE inside of your sum:
select p.id, p.name,
t.id as toyid,
t.name as toyname
from person p
inner join toys t on p.id = t.person_id
inner join
(
select person_id
from toys
group by person_id
having sum(case when name = 'hat' then 1 else 0 end) > 0 and
sum(case when name = 'doll' then 1 else 0 end) > 0
) t2
on p.id = t2.person_id;
See SQL Fiddle with Demo

Related

SQL code in Access says error in FROM clause

SELECT
p.Name,
p.Age,
MAX(COUNT(m.winTeam_ID) / (COUNT(m.winTeam_ID) + COUNT(m.lossTeam_ID)))
FROM Players AS p
INNER JOIN Teams AS t
ON t.ID = p.Team_ID
INNER JOIN Matches AS m
ON m.Team_ID = t.ID
GROUP BY
p.Name,
p.Age;
I can suggest the following query:
SELECT TOP 1
p.Name,
p.Age,
COUNT(m.winTeam_ID) / (COUNT(m.winTeam_ID) + COUNT(m.lossTeam_ID))
FROM (Players AS p
INNER JOIN Teams AS t
ON t.ID = p.Team_ID)
INNER JOIN Matches AS m
ON m.Team_ID = t.ID
GROUP BY
p.Name,
p.Age
ORDER BY
COUNT(m.winTeam_ID) / (COUNT(m.winTeam_ID) + COUNT(m.lossTeam_ID)) DESC;
This fixes the syntax problem with your joins. It also interprets the MAX as meaning that you want the record with the maximum ratio of counts. In this case, we can use TOP 1 along with ORDER BY to identify this max record.
MS Access requires strange parentheses when you have more than one join. In addition, MAX(COUNT(m.winTeam_ID)) doesn't make sense. I don't know what you are trying to calculate in the SELECT. Perhaps this does what you want:
SELECT p.Name, p.Age,
COUNT(m.winTeam_ID) / (COUNT(m.winTeam_ID) + COUNT(m.lossTeam_ID)))
FROM (Players AS p INNER JOIN
Teams AS t
ON t.ID = p.Team_ID
) INNER JOIN
Matches AS m
ON m.Team_ID = t.ID
GROUP BY p.Name, p.Age;
I think your Matches table shouldn't have a Team_ID And instead you have winTeam_ID and lossTeam_ID!
And also you want to query players of a team with - something like - the best win-rate.
If so, Use a query like this - tested on SQL Server only -:
select
p.Age, p.Name, ts.rate
from
Players p
join
(select top(1) -- sub-query will return just first record
t.ID
, sum(case when (t.ID = winTeam_ID) then 1 else 0 end) as wins
, sum(case when (t.ID = lossTeam_ID) then 1 else 0 end) as losses
, sum(case when (t.ID = winTeam_ID) then 1.0 else 0.0 end) /
(sum(case when (t.ID = winTeam_ID) then 1.0 else 0.0 end) + sum(case when (t.ID = lossTeam_ID) then 1.0 else 0.0 end)) as rate
from Teams as t
left join Matches as m
on t.ID = m.winTeam_ID
or t.ID = lossTeam_ID
group by t.ID
order by rate desc -- This will make max rate as first
) as ts -- Team stats calculated in this sub-query
on p.Team_ID = ts.ID;

whats wrong with my code(sub query - sql server)

I am getting incorrect syntax near ')', c an someone suggest what i am doing wrong? I am trying to get my self familiar with sub queries and thanks in advance!
attached is the sql that i wrote and trying to modify here us the SQL script
(
SELECT
APP_ID,
MAX(CASE WHEN CUST_TYPE_ORD_NUM = 0 THEN CUST_APP_ID END) AS PRI_CUST_APP_ID,
MAX(CASE WHEN CUST_TYPE_ORD_NUM = 1 THEN CUST_APP_ID END) AS SEC_CUST_APP_ID,
....
....
FROM
(
SELECT
APP_ID,
CUST.CUST_ID,
CUST_TYPE_ORD_NUM
..
FROM CDM_CUST_APP_MTRX CUST_APP_MTRX
LEFT JOIN CDM_CUST CUST ON CUST_APP_MTRX.CUST_ID = CUST.CUST_ID
) CUST_MTRX
GROUP BY APP_ID
) ABC
LEFT JOIN CDM_CUST_ADR_DETL CUST_ADR_DETL
ON ABC.PRI_CUST_APP_ID = CUST_ADR_DETL.CUST_APP_ID
LEFT JOIN CDM_CUST_ADR_DETL CUST_ADR_DETL2
ON ABC.PRI_CUST_APP_ID = CUST_ADR_DETL2.CUST_APP_ID
It is a syntax issue. Write one more SELECT * FROM before first bracket in the first line of the query.
SELECT * FROM (
SELECT
APP_ID,
MAX(CASE WHEN CUST_TYPE_ORD_NUM = 0 THEN CUST_APP_ID END) AS PRI_CUST_APP_ID,
MAX(CASE WHEN CUST_TYPE_ORD_NUM = 1 THEN CUST_APP_ID END) AS SEC_CUST_APP_ID
FROM
(
SELECT
APP_ID,
CUST.CUST_ID,
CUST_TYPE_ORD_NUM,
..
FROM CDM_CUST_APP_MTRX CUST_APP_MTRX
LEFT JOIN CDM_CUST CUST ON CUST_APP_MTRX.CUST_ID = CUST.CUST_ID
) CUST_MTRX
GROUP BY APP_ID
) ABC
LEFT JOIN CDM_CUST_ADR_DETL CUST_ADR_DETL
ON ABC.PRI_CUST_APP_ID = CUST_ADR_DETL.CUST_APP_ID
LEFT JOIN CDM_CUST_ADR_DETL CUST_ADR_DETL2
ON ABC.PRI_CUST_APP_ID = CUST_ADR_DETL2.CUST_APP_ID

How to get multiple counts in one sql query across multiple tables

I have 2 tables
Company & products
I need to get 2 counts. One is the total count of products and the secondly count of products for sale_flg=1
This SQL does not seem to work..Tried several other ways..not able to get the expected results
SELECT A.COMPANY_NAME, COUNT(B.PRODUCT_ID) AS TOTAL_COUNT_OF_PRODUCTS,
(CASE WHEN B.SALEFLG =1 THEN 1 END) AS COUNT_OF_SALES
FROM COMPANY A LEFT JOIN
PRODUCT B
ON B.COMPANY_ID = A.COMPANY_ID
GROUP BY A.COMPANY_NAME
I think you just need a sum for the case:
SELECT C.COMPANY_NAME, COUNT(P.PRODUCT_ID) AS TOTAL_COUNT_OF_PRODUCTS,
SUM(CASE WHEN P.SALEFLG = 1 THEN 1 ELSE 0 END) AS COUNT_OF_SALES
FROM COMPANY C LEFT JOIN
PRODUCT P
ON P.COMPANY_ID = C.COMPANY_ID
GROUP BY C.COMPANY_NAME ;
If you have B.SALEFLG = 1 or 0 for you may try
Sum(B.SALEFLG) AS COUNT_OF_SALES
Or use UNION
If you use count then in else you should consider null because null is not consider in count aggregation and if you have B.SALEFLG =1 or 0 then use sum aggregation.
You can try below code:
SELECT A.COMPANY_NAME, COUNT(B.PRODUCT_ID) AS TOTAL_COUNT_OF_PRODUCTS,
count(CASE WHEN B.SALEFLG =1 THEN 1 else null END) AS COUNT_OF_SALES
FROM COMPANY A LEFT JOIN
PRODUCT B
ON B.COMPANY_ID = A.COMPANY_ID
GROUP BY A.COMPANY_NAME
OR try this:
SELECT A.COMPANY_NAME, COUNT(B.PRODUCT_ID) AS TOTAL_COUNT_OF_PRODUCTS,
sum(B.SALEFLG) AS COUNT_OF_SALES
FROM COMPANY A LEFT JOIN
PRODUCT B
ON B.COMPANY_ID = A.COMPANY_ID
GROUP BY A.COMPANY_NAME
This SQL server query is working.
Company Table and Product Table
Company Table CompanyID is join with Product table and sales_flg add in product table .
sales_flg = 1 record display in CntSalesflg
select Comp.CompID as CompID, COUNT(Pro.ProductID) as CntProdustID,
SUM(CASE WHEN Pro.SalesflagID = 1 THEN 1 ELSE 0 END) as CntSalesflg
from Product as Pro
inner join Company as Comp on Pro.CompID = Comp.CompID
GROUP by Comp.CompID

Invalid column name error while using left join

I am getting Invalid column name 'PostId' error while executing the following query
Select a.SuburbDiscussionID,SUM((CASE WHEN b.postcnt IS NULL THEN 0 ELSE b.postcnt END) + (CASE WHEN c.replycnt IS NULL THEN 0 ELSE c.replycnt END)) AS TotCount
from SuburbDiscussions a
left join (SELECT COUNT(*) as postcnt,Posts.DiscussionId FROM Posts
GROUP BY Posts.DiscussionId) b on a.DiscussionId = b.DiscussionId
left join (SELECT COUNT(*) as replycnt,PostComments.PostId FROM PostComments
GROUP BY PostComments.PostId) c on b.PostId = c.PostId
where a.IsDelete = 0 and a.UserID != 33
Group by a.SuburbDiscussionID
ORDER BY TotCount
Why PostId column not detecting in my query?

Joined SQL query MAX aggregate with condition

I am having trouble with a SQL query. Here is a representation of my schema on SQL Fiddle:
http://sqlfiddle.com/#!15/14c8e/1
The issue is that I want to return rows of data from the Invitations table and join them with a sum of both the 'sent' event_type and 'viewed' event_type from the associated events, as well as the latest created_at date.
I can get all the data and counts working, but am having issue with the last_sent_on. Is there a way I can use a condition in a MAX aggregate function?
e.g.
MAX(
SELECT events.created_at
WHERE event_type='sent'
)
If not, how would I write the proper subselect?
I am currently using Postgresql.
Thank you.
You can use a case statement inside of max just as you've done with sum. The query below will select the maximum created_at for event_type='sent'
SELECT
i.id,
i.name,
i.email,
max(case when e.event_type='sent' then e.created_at end) AS last_sent_on,
sum(case when e.event_type='sent' then 1 else 0 end) AS sent_count,
sum(case when e.event_type='viewed' then 1 else 0 end) AS view_count
FROM
invitations i
LEFT OUTER JOIN
events e
ON e.eventable_id = i.id
WHERE e.eventable_type='Invitation'
GROUP BY i.id, i.name, i.email
SQLFiddle
Try using a subquery to build the max value for sent.
SELECT
i.id,
i.name,
i.email,
sent.last_sent,
sum(case when e.event_type='sent' then 1 else 0 end) AS sent_count,
sum(case when e.event_type='viewed' then 1 else 0 end) AS view_count
FROM
invitations i
LEFT OUTER JOIN
events e
ON e.eventable_id = i.id
LEFT JOIN ( SELECT eventable_id uid, MAX(created_at) AS last_sent
FROM events
WHERE event_type = 'sent'
GROUP BY eventable_id ) AS sent
ON sent.uid = i.id
WHERE e.eventable_type='Invitation'
GROUP BY i.id, i.name, i.email, sent.last_sent