0

背景

我有一个 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 | [UK] | 2013-04-20 | 70
1 | 2 | [UK] | 2013-04-20 | 70

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

4

1 回答 1

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)

然后是带有字段 id/platform_id/date/price 的国家/地区表 (tbl_country)

然后是带有字段 id/country_id/date/price 的区域表 (tbl_region)

如果你想要基地信息,直接从基地表中获取,如果你想要地区信息,将地区加入国家,然后加入基地。

于 2013-03-20T04:23:24.133 回答