1

I have three tables:

  • Subscriptions
    SubscriptionID
    SubscriptionName
    Inherits (can be NULL)

  • SubscriptionOptions
    SubscriptionOptionID
    SubscriptionID
    OptionID
    OptionValue

  • Options
    OptionID
    OptionDefaultValue
    Description

I need to pass in a query with multiple options and a subscription ID, something along these lines:

SELECT optionid, optionvalue WHERE subscriptionid = x AND options IN (a, b, c, d, e, f)

Only I need to implement the inherits by logic via a recursive call like this:

if subscriptionoption exists for subscription id & optionid
    use subscriptionoption.optionvalue in the row
else
    if inherits is not NULL
        call this function using inherited subscription id
    else
        use options.optiondefaultvalue for that optionid
3
  • I need some clarification on the "repeat this process" part. What are you trying to repeat? What exactly are you trying to accomplish if the subscriptionoption record doesn't exist, and inherits is not null? Because I don't see how repeating any part of the process would ever have different results, and would just be an infinite loop (unless you mean to keep checking repeatedly until inherits is null or the subscriptionoption record is found, which would be a very bad idea). Commented Jul 12, 2012 at 23:51
  • Sorry hope that clarifies, just mean to repeat the process only using the subscriptionid found in inherits Commented Jul 13, 2012 at 1:01
  • Proper sample code (here, SQL statements) is more useful than any ad hoc schema and sample data format. Please use CREATE TABLE and INSERT ... VALUES for samples. Desired results don't need to be presented as sample code, as results are the output of code and not code themselves. Commented Jul 17, 2012 at 22:36

1 Answer 1

1

To do it in SQL, I think you need to incorporate a hierarchical query. Here's a swing at it, but I haven't been able to test it out.

SELECT optionID, NVL( MAX(optionValue), MAX(optionDefaultValue) ) optionValue
FROM (SELECT optionID, optionDefaultValue, subscriptionID, inherits
        FROM options CROSS JOIN subscriptions
        WHERE optionID IN (a,b,c,d,e,f)
     )
     LEFT JOIN subscriptionOptions USING (optionId, subscriptionID)
START WITH subscriptionID = x
CONNECT BY PRIOR optionValue IS NULL
       AND subscriptionID = PRIOR inherits
       AND optionID = PRIOR optionID
GROUP BY optionID

Another approach would be to write a function that implements the recursive logic for a single subscriptionID and optionID, then call it like this:

SELECT optionID, NVL( getSubscriptionOption( x, optionID), optionDefaultValue )
  FROM options
  WHERE optionID IN (a,b,c,d,e,f)

The function could be something like:

FUNCTION getSubscriptionOption( pSubID NUMBER, pOptID NUMBER )
  RETURN subscriptionOptions.optionValue%TYPE
  IS
    l_optionValue subscriptionOptions.optionValue%TYPE;
    l_inherits    subscriptionOptions.inherits%TYPE;
  BEGIN
    SELECT optionValue
      INTO l_optionValue
      FROM subscriptionOptions
      WHERE subscriptionID = pSubID
        AND optionID = pOptID;
    RETURN l_optionValue;
  EXCEPTION
    WHEN no_data_found THEN
      SELECT inherits
        INTO l_inherits
        FROM subscriptions
        WHERE subscriptionID = pSubID;
      IF inherits IS NULL THEN
        RETURN NULL;
      ELSE
        RETURN getSubscriptionOption( l_inherits, pOptID );
      END IF;
  END;

or could be written to use a loop instead of recursion.

Sign up to request clarification or add additional context in comments.

3 Comments

Well couldn't get the hierarchical query to work, but doing the recursive function worked like a charm. Certainly a correct answer and I appreciate it. One question, will the recursive method be incredibly less efficient then the built in hierarchical method? Just wondering...
I wouldn't make any prediction about the relative efficiency of the two methods, without (a) having a query that actually works, then (b) seeing its execution plan. The function has additional overhead due to context switches, but it could end up being faster if the single query can't be optimized well. The only way to really know is try both methods.
I set up a little test data set and tried the hierarchical query on it. It seems to give the correct results (and produces a pretty interesting execution plan). What's the problem you're having with it?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.