带有/ multiplication的SQL逻辑和/或PHP应用程序;另外(我采取正确的方法还是全部错了?)

时间:2012-01-20 17:37:20

标签: php mysql sql

我正在为应用程序问题制作一些伪代码。我想要一些建议,如果我是否在这里正确地走在正确的轨道上,还是我认为这一切都错了?

我有3个查询条目值:

申请人年龄
配偶年龄
儿童人数

对于上述每个值,我的费率表中都有一个费率。例如,对于申请人年龄> 65,我的价格是50.00美元。和配偶年龄> = 18或< = 64,我的价格是40.00美元。孩子们有同样的方式,但可能有多个孩子。

以下是我的问题的细分:

  1. 每个申请人类型(申请人,配偶和子女)有一条记录。每种类型都有自己的价格。

  2. 我需要在SQL的范围内返回总速率结果(这是我希望的),所以我可以将它构建到我现有的查询中。所以基本上我试图根据SQL中的一些数学创建一个“神奇地出现”的记录。换句话说,我的费率表中没有包含此结果金额的记录,它将在SQL的范围内计算。

  3. 真实示例: appliant_age = 24(费率$ 50.00),spouse_age = 20(费率$ 40.00),number_of_children = 3(费率$ 20 x 3(输入的数字)费率$ 60.00)。总费率= 150.00美元。

    应该创建一个“魔术结果”记录,该记录只能构建到我的标准SQL结果中(已经存在并且正在工作)。根据我的例子,它将是150.00美元。我也应该能够从查询中将此值传递给我的脚本。

    我的主要费率表(带适用字段)设置如下:

    CREATE TABLE `rates` (
      `id` int(11) NOT NULL auto_increment,
      ...
      `monthly_cost` decimal(18,2) NOT NULL,
      `age_id` int(11) NOT NULL, // e.g. 0-17 (child), 18-65 (adult), 65+ (elder) etc...
      PRIMARY KEY  (`id`)
    )
    

    不,我不是在寻找任何人为我写代码。只是需要一些指导,这是解决这个问题的最佳逻辑方法。

2 个答案:

答案 0 :(得分:1)

我知道你不需要代码,但代码是表达我的指导的最简单方法......

假设申请人,配偶和子女通过一个身份证(application_id)相关,可能会有一个包含以下字段的表格,可能更多......

application_id | applicant_type_id | applicant_id | age
       1                 1                 1         24
       1                 2                 2         20
       1                 3                 3          9
       1                 3                 4          7
       1                 3                 5          6

然后另一张表格有... ...

applicant_type_id | inclusive_age | exclusive_age | rate
        1                18              25          50
        1                25              35          60
        1                35              45          70
        1                45              55          80
        1                55              65          90
        1                65              200        100
        2                18              25          40
        2                25              35          50
        2                35              45          60
        2                45              55          70
        2                55              65          80
        2                65              200         90
        3                 0              2            0
        3                 2              6           10
        3                 6             10           20
        3                10             14           30
        3                14             18           40

查询类似于......

SELECT
  applicant.application_id,
  SUM(rate.rate)             AS total_rate
FROM
  applicant
INNER JOIN
  rate
    ON  rate.applicant_type_id  = applicant.applicant_type_id
    AND rate.inclusive_age     <= applicant.age
    AND rate.exclusive_age     >  applicant.age
GROUP BY
  applicant.application_id

答案 1 :(得分:0)

如果..

  

儿童以同样的方式拥有自己的比率,但可能有多个孩子。

然后你的概念需要更多细节。您需要每个孩子的年龄,因为费率取决于它。

对于每个申请人的0-n个孩子,您创建一个额外的表格,并通过外键与申请人以n:1的关系连接。表格布局可能如下所示:

CREATE TABLE applicant (
  applicant_id integer PRIMARY KEY
 ,applicant    text NOT NULL
 ,age          integer NOT NULL
 ,spouse_age   integer NOT NULL -- 0 for "no spouse"
);

CREATE TABLE child (
  child_id     integer PRIMARY KEY
, applicant_id integer NOT NULL REFERENCES applicant (applicant_id)
, age          integer NOT NULL
);

CREATE TABLE rate (
  rate_id integer PRIMARY KEY
, type    text NOT NULL        -- 'a' .. applicant, 's' .. spouse, 'c' .. child
, age_min integer NOT NULL
, age_max integer NOT NULL
, amount  integer NOT NULL
);

您会强制执行每种类型的互斥费率,因此任何年龄的任何类型都不会超过一行。此外,0岁的配偶没有率。

然后查询可能如下所示:

SELECT a.application_id
     , a.applicant
     , COALESCE(ra.amount, 0)
     + COALESCE(rs.amount, 0)
     + COALESCE(rc.amount, 0) AS total_amount
FROM   applicant AS a
LEFT   JOIN rate AS ra ON  r.type = 'a'
                       AND a.age BETWEEN ra.age_min AND ra.age_max
LEFT   JOIN rate AS rs ON  r.type = 's'
                       AND a.spouse_age BETWEEN rs.age_min AND rs.age_max
LEFT   JOIN (
       SELECT c.application_id, sum(r.amount) AS amount
       FROM   child AS c
       LEFT   JOIN rate AS r ON  r.type = 'c'
                             AND c.age BETWEEN rc.age_min AND rc.age_max
       GROUP  BY c.applicant_id
       ) AS rc ON rc.applicant_id = a.applicant_id

子查询在加入申请人之前总结了可变数量的孩子 LEFT JOIN允许“没有配偶”或“没有孩子”。