1

我有三张桌子:

  • Subscriptions
    SubscriptionID
    SubscriptionName
    Inherits(可以为 NULL)

  • SubscriptionOptions
    SubscriptionOptionID
    SubscriptionID
    OptionID
    OptionValue

  • 选项
    OptionID
    OptionDefaultValue
    描述

我需要传入一个带有多个选项和订阅 ID 的查询,大致如下:

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

只有我需要通过这样的递归调用通过逻辑实现继承:

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
4

1 回答 1

1

要在 SQL 中执行此操作,我认为您需要合并分层查询。这是一个摇摆,但我无法测试它。

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

另一种方法是编写一个函数,为单个 subscriptionID 和 optionID 实现递归逻辑,然后像这样调用它:

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

该函数可能类似于:

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;

或者可以写成使用循环而不是递归。

于 2012-07-13T01:44:38.400 回答