Home > Software design >  Orcale - Missing Right Paranthesis
Orcale - Missing Right Paranthesis

Time:10-11

I am trying to run an oracle query using, Case when and Sum together, It gives me an error saying I am missing the right paranthesis.

The query below,

SELECT  c.Customer_name,
        CASE WHEN SUM(status = 'DELIVERED') = count(*) THEN 'A'
            WHEN SUM(status = 'DELIVERED') > 0  THEN 'B'
            WHEN SUM(status = 'SUBMITTED') > 0  THEN 'C'
             ELSE 'No Match'
        END AS Match
FROM    Customer_Order c
group by c.Customer_name order by c.Customer_name;

Changed my query to look like this and it says, I am missing keyword

SELECT  c.Customer_name,
        CASE WHEN SUM(c.status) = 'DELIVERED' = (count(c.status)) THEN 'A'
            WHEN SUM(c.status) = 'DELIVERED' > 0  THEN 'B'
            WHEN SUM(c.status) = 'SUBMITTED' > 0  THEN 'C'
             ELSE 'No Match'
        END AS Match
FROM    Customer_Order c
group by c.Customer_name order by c.Customer_name;

CodePudding user response:

Ok, what I think you are trying to do includes counting all the cases where status = 'DELIVERED' and status = 'SUBMITTED' and then comparing those with something to determine what the outcome is. But you can't sum a conditional expression like status = 'DELIVERED' so you need to do it in two steps: one to make a number out of the conditional and one to compare the sum with something.

Step 1: To count the cases where status = 'DELIVERED' you need a column that is 1 when the status is DELIVERED and 0 when it is not (and the same with 'SUBMITTED'). That way you have numbers to sum. So the data we want to run your query on is:

SELECT *,
  CASE WHEN status = 'SUBMITTED' THEN 1 ELSE 0 END AS Is_submitted,
  CASE WHEN status = 'DELIVERED' THEN 1 ELSE 0 END AS Is_delivered
FROM Customer_order

Step 2: Now we can use your query on the results of Step 1:

SELECT
  c.Customer_name,
  CASE WHEN SUM(c.delivered) = count(*) THEN 'A'
       WHEN SUM(c.delivered) > 0 THEN 'B'
       WHEN SUM(c.submitted) > 0 THEN 'C'
       ELSE 'No Match'
  END AS X
FROM (the query above) as c
GROUP BY c.Customer_name
ORDER BY c.Customer_name;

Substituting Step 1 into Step 2 we get the actual query:

SELECT
  c.Customer_name,
  -- SUM(c.Is_delivered),
  -- SUM(c.Is_submitted),
  -- count(*),
  CASE WHEN SUM(c.delivered) = count(*) THEN 'A'
       WHEN SUM(c.delivered) > 0 THEN 'B'
       WHEN SUM(c.submitted) > 0 THEN 'C'
       ELSE 'No Match'
  END AS X
FROM (
  SELECT *,
    CASE WHEN status = 'SUBMITTED' THEN 1 ELSE 0 END AS submitted,
    CASE WHEN status = 'DELIVERED' THEN 1 ELSE 0 END AS delivered
  FROM Customer_order
) as c
GROUP BY c.Customer_name
ORDER BY c.Customer_name;

Try it here:

https://www.db-fiddle.com/f/mSdREEgU1mT1pvczG2kZgm/1

CodePudding user response:

You appear to be trying to count true comparions; unlike some other languages, in SQL a true value is not the same as 1 and a false value is not 0 so you need to use a CASE expression to convert the comparison to something that can be summed (or counted).

In this case, you can use conditional aggregation:

SELECT Customer_name,
       CASE
       WHEN COUNT(CASE status WHEN 'DELIVERED' THEN 1 END) = COUNT(status)
       THEN 'A'
       WHEN COUNT(CASE status WHEN 'DELIVERED' THEN 1 END) > 0
       THEN 'B'
       WHEN COUNT(CASE status WHEN 'SUBMITTED' THEN 1 END) > 0
       THEN 'C'
       ELSE 'No Match'
       END AS Match
FROM   Customer_Order
group by Customer_name
order by Customer_name;
  • Related