使SQL记录从同一个表中的一个或多个记录继承值

时间:2013-03-10 20:53:32

标签: php mysql sql mysqli

背景

我有一个MySQL表,每个记录代表一个区域和/或平台特定的项目版本。对于任何给定的项目,将有几个版本;没有主键,主要是索引列。

我从全球记录开始,每个平台版本一个。然后,我为任何特定于区域的值添加记录,然后为任何特定于国家/地区的值添加记录。问题是我只计划添加该地区或国家独有的价值;换句话说,所有记录都将具有空值,因为我不想输入重复值,所以我希望记录从其他记录继承值。

item | platform | region | country | date       | price | [...]
1    | 1        | [WW]   | null    | 2013-04-01 | 100   |
1    | 2        | [WW]   | null    | 2013-04-01 | 100   |
1    | null     | [EU]   | null    | 2013-04-20 | 80    |
1    | null     | [UK]   | null    | null       | 70    |

我计划使用PHP显示给定国家/地区的相关记录。问题是,我希望能够结合/继承该国家的地区记录和全球记录中的值。因此,英国将有两个总记录:每个记录从platform记录继承[WW]值,两者都继承date记录中的[EU]值,两者都具有price记录来自[UK]记录的{1}}值。

1 | 1 | [UK] | 2013-04-20 | 70
1 | 2 | [UK] | 2013-04-20 | 70

我想知道的问题是在MySQL中只有一个解决方案/程序/方法吗?或者唯一的方法是通过PHP编码?

1 个答案:

答案 0 :(得分:1)

您要求的内容

请注意,这不是一个真正的答案。它只输出你在问题中提出的问题,但这里的逻辑几乎没有任何意义,所以它不太可能适用于真正的数据库。

SELECT a.item, b.platform, a.region, a.country, c.date, a.price FROM
    (SELECT item, region, country, price FROM table WHERE platform IS NULL AND date IS NULL GROUP BY item) AS a
    LEFT JOIN 
        (SELECT platform FROM table WHERE platform IS NOT NULL) AS b 
    ON a.item = b.item 
    LEFT JOIN 
        (SELECT date FROM table WHERE PLATFORM IS NULL AND date IS NOT NULL) AS c 
    ON a.item = c.item 

更好地回答

更有条理,更简单的方式(如果你不超过2层父母,仍然有效)将是:

 id | parent_id | item | platform | region | country | date       | price | [...]
 1  | null      | 1    | 1        | [WW]   | null    | 2013-04-01 | 100   |
 2  | null      | 1    | 2        | [WW]   | null    | 2013-04-01 | 100   |
 3  | 1         | 1    | null     | [EU]   | null    | 2013-04-20 | 80    |
 4  | 2         | 1    | null     | [UK]   | null    | null       | 70    |

SELECT items.*, 
parent_items.platform AS pa_platform, parent_items.region AS pa_region, parent_items.country AS pa_country, parent_items.date AS pa_date, parent_items.price AS pa_price,  
grandparent_items.platform AS gpa_platform, grandparent_items.region AS gpa_region,  parent_items.country AS gpa_country, parent_items.date AS gpa_date, parent_items.price AS gpa_price
FROM items
LEFT JOIN 
    items AS parent_items
ON items.parent_id = parent_items.id
LEFT JOIN 
    items AS grandparent_items
ON parent_items.parent_id = grandparent_items.id

然后您可以选择使用应用级逻辑来显示最接近的非空值:

$region = $result['region'] ? $result['region'] : ($result['pa_region'] ? $result['pa_region'] : $result['gpa_region']);

或者您可以修改上面的SQL以选择第一个非空值:

SELECT COALESCE(items.region, parent_items.region, grandparent.region) AS region, COALESCE(items.platform, parent_items.platform, grandparent.platform) AS platform, ...

现在......如果您确实要添加具有依赖关系的行

为什么不简单地制作不同的表?

假设您将为每个地区,每个平台,每个国家/地区定价,并且您知道优先顺序(例如,作为示例区域>国家>平台):

为什么不用字段id / item / platform / date / price

制作基表(tbl_platform)

然后是一个国家表(tbl_country),其字段为id / platform_id / date / price

然后是一个区域表(tbl_region),其字段为id / country_id / date / price

如果您想要基本信息,只需直接从基表中获取,如果您想要区域信息,请将该区域加入该国家/地区,然后加入基地。