2013-03-10 51 views
0

背景从一个或多个记录在同一个表

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

我从世界范围的记录开始,每个平台版本的项目都有一个记录。然后,我为任何特定于区域的值添加记录,然后为任何特定于国家/地区的值添加记录。问题是我只打算增加对该地区或国家来说独一无二的价值;换句话说,所有记录都会有空值,因为我不想输入重复的值,所以我希望记录继承其他记录的值。

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来显示给定国家的相关记录。事情是,我希望能够结合/继承该国区域记录和全球记录的价值。因此,英国将有两条记录:每条记录从[WW]记录继承platform值,它们都从[EU]记录继承date值,并且两条记录的[UK]记录的值均为price

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

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

+0

澄清:我认为我们需要一个固定的逻辑在这里,所以你想要做到这一点?选择以null作为平台并以null作为日期的行,将它们以非null作为平台的相同item#连接起来,获取平台。然后加入null作为平台,非空作为日期,获取日期。如果是这种情况,那么它很容易实现,但你最好用多个表格。 – 2013-03-10 21:11:57

+0

有更多列比显示;这不仅仅是我展示的那些。无论如何,我应该有单独的“平台可用性”,“全球”,“区域”和“国家”表吗? – 2013-03-11 22:10:19

+0

它仍然取决于你的逻辑。一些要问的问题:你的逻辑告诉程序要显示(1 | 1 | UK,1 | 2 | UK)而不是(1 | 1 | EU,1 | 2,EU)?如果你有一个“WW表”作为原型和一个真正的“物品”表,或者你必须把它们放在一起,因为你计划通过任意数量的“父”项(英国 - >欧盟 - > WW或AU - > WW或芝加哥 - > IL - > US - > WW),在这种情况下,您需要在同一个表格中添加一个名为“parent_item_id”的额外字段。 – 2013-03-12 04:30:39

回答

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, ... 

现在...如果你实际上要依赖与添加行

为什么不干脆让不同表?

假设你必须为每个区域,每一个平台,每一个国家的价格,你知道的优先顺序(比方说作为一个例子区>国家>平台):

何不做一个基地表(tbl_platform)与域ID /项目/平台/日期/价格

然后一国表(tbl_country)与域ID /平台_id /日期/价格

随后区表(tbl_region)与域ID/country_id/date/price

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

+1

我现在有平台,价格,评分,封面,标题和发布日期的单独表格。除了平台表,“区域”和“国家”列以及表格专用列的价格等外,它们每个都有。我使用这种设置,因为国家版本可以有不同的或相同的价格/封面/ title/date/rating作为区域。基本上对于给定的国家/地区页面,我希望给定属性表中的国家/地区记录优先于同一表中的任何匹配区域记录。感谢您的输入;我正在处理这项新任务。 – 2013-03-22 00:26:59

+0

不客气,很高兴你的逻辑清理了。这就是为什么我们总是从逻辑 - >数据库 - >(控制器<->查看) – 2013-03-22 02:32:31

相关问题