0

需要在 Oracle 中设计一个表,这些是我的列:

  1. 国家
  2. 产品
  3. 参数 1
  4. 参数2
  5. 参数 3

我的第一个想法是,我希望 Country 和 Product 的组合成为一个 PK。但是,对于不属于 Country + Product 记录的任何内容,我也想要一个包罗万象的/默认值。例子:

  • 产品 A 和美国国家:参数值如下 1,1,1
  • 所有产品的国家/地区:参数值为 2、2、2:我应该为每个可能的产品记录吗?是否有可能对法国和所有产品进行记录?
  • 任何其他国家和产品组合都有参数 3、3、3:在不为每个国家和产品创建记录的情况下实现这一目标的最佳方法是什么。国家/地区可能不会发生太大变化,但我可以一直获得新产品,我不想每次发生这种情况时都更新此表

看起来我应该让 Product 和 Country 可以为空而不是 PK,但我想知道我是否遗漏了任何其他选项。

任何想法将不胜感激。

干杯!

4

1 回答 1

1

一种可能性是使用virtual columns

CREATE TABLE country_parms
    (country                        VARCHAR2(50 CHAR),
    product                        VARCHAR2(50 CHAR),
    param1                         VARCHAR2(50 CHAR),
    param2                         VARCHAR2(50 CHAR),
    param3                         VARCHAR2(50 CHAR),
    country_nn                     VARCHAR2(50 CHAR) GENERATED ALWAYS AS (NVL("COUNTRY",'-')) ,
    product_nn                     VARCHAR2(50 CHAR) GENERATED ALWAYS AS (NVL("PRODUCT",'-')) ,
    PRIMARY KEY  (country_nn, product_nn)
    )

使用这种方法,您还可以对您的countryproduct表使用 fk-constraints。要选择值,请使用如下视图:

SELECT c.country
     , p.product
     , CASE WHEN cp1.country_nn IS NOT NULL THEN cp1.param1
            WHEN cp2.country_nn IS NOT NULL THEN cp2.param1
            WHEN cp3.country_nn IS NOT NULL THEN cp3.param1
            ELSE cp4.param1
       END param1
     , CASE WHEN cp1.country_nn IS NOT NULL THEN cp1.param2
            WHEN cp2.country_nn IS NOT NULL THEN cp2.param2
            WHEN cp3.country_nn IS NOT NULL THEN cp3.param2
            ELSE cp4.param2
       END param2
     , CASE WHEN cp1.country_nn IS NOT NULL THEN cp1.param3
            WHEN cp2.country_nn IS NOT NULL THEN cp2.param3
            WHEN cp3.country_nn IS NOT NULL THEN cp3.param3
            ELSE cp4.param3
       END param3
  FROM country c
 CROSS JOIN product p
  LEFT JOIN country_parms cp1
    ON cp1.country_nn = c.country
   AND cp1.product_nn = p.product
  LEFT JOIN country_parms cp2
    ON cp2.country_nn = c.country
   AND cp2.product_nn = '-'
  LEFT JOIN country_parms cp3
    ON cp3.country_nn = '-'
   AND cp3.product_nn = p.product
  LEFT JOIN country_parms cp4
    ON cp4.country_nn = '-'
   AND cp4.product_nn = '-'

使用所有国家和产品的叉积,然后首先寻找精确匹配,然后是产品为空的地方,然后是国家/地区为空的地方,最后都是空的地方以获得参数的配置。

甚至更简单:

  SELECT MAX(param1) KEEP (DENSE_RANK FIRST ORDER BY country nulls last
                                                   , product nulls last) param1
       , MAX(param2) KEEP (DENSE_RANK FIRST ORDER BY country nulls last
                                                   , product nulls last) param2
       , MAX(param3) KEEP (DENSE_RANK FIRST ORDER BY country nulls last
                                                   , product nulls last) param3                                              
    FROM country_parms
   WHERE country_nn IN (:country_nn, '-')
     AND product_nn IN (:product_nn, '-')
于 2019-08-30T14:11:28.347 回答