2012-10-15 14 views
0

我已经就如何解决这个SQL没有对线索:MySQL的:从表中选择的所有记录与ID,请参阅架构

表ADS:

ad_id 
ad_title 
ad_type_id 

.... 表ADS_DATA:

ad_data_id 
ad_id 
ad_data_name 
ad_data_value 

好吧,让尽量做到简单:表ADS存储通用数据的类型ad_type_id的对象。表ADS_DATA根据其ad_type_id存储对象的额外数据。

ADS_DATA.ad_data_name存储数据的名称(在普通表中将是列名), ADS_DATA.ad_data_value存储此数据的值。 取决于ad_type_id,ADS_DATA表填充了特定的ad_data_name值。 如:

ADS 
ad_id = 1,ad_type_id = 2 
ad_id = 2,ad_type_id = 3 
ADS_DATA 
ad_data_id = 1,ad_id = 1,ad_data_name = 'rooms',ad_data_value = 2 
ad_data_id = 2,ad_id = 1,ad_data_name = 'size',ad_data_value = 20 
ad_data_id = 3,ad_id = 2,ad_data_name = 'fingers',ad_data_value = 15 
ad_data_id = 4,ad_id = 2,ad_data_name = 'toes',ad_data_value = 5 

OK,我如何得到ADS_DATA包含所有行和具体ad_id(每一行,尽管它的名称或值),其中(ad_data_name = x和ad_data_value = y)和(ad_data_name = X1和ad_data_value = y2)AND ...

我知道这是一个huuuugge混乱,但感谢阅读!

更新: 下面是一个例子:即时通讯试图建立一个不同类别的广告系统(ADS.ad_type_id)。根据您选择哪种类型的广告,ads_data表中填充了该类别的特定数据,例如: AD房屋类别,将在ads_data表中包含:房间,大小,浴池...... 我可以创建一个ads_data表与每个类别的所有可能的数据的名称列,并填写只有我需要的,但我认为这是一种浪费,所以决定创建列的表:

ad_data_id  UNIQUE ID 
ad_id    REFERENCE TO ADS.ad_id 
ad_data_name  for the "column name",e.g: house_rooms 
ad_data_value  for the value. 

INSTEAD OF A "NORMAL" RELATION: 
ad_data_id  UNIQUE ID 
ad_id    REFERENCE TO ADS.ad_id 
house_rooms  ad data,only fill columns relative to choseen category(e.g:house_) 
house_size 
house_baths 
car_engine 
car_hp 
car_year 
... 

我想通过ADS表进行搜索(例如通过广告价格进行过滤(这是所有广告的常用数据,所以它在ADS表中,而不是ADS_DATA),然后仅获取具有以下内容的行:(house_rooms BETWEEN X AND Y)和(house_size在A和B之间)。我需要一个'AND'而不是'OR',在ADS_DA之间TA专栏。你认为做一个“正常”表更好(也许是唯一的方法),只填写我需要的每个类别的列?

感谢

更新:虽然有很多谷歌在那里反对使用键/值对的这个建议,我已经找到了,尽管性能命中,解决方案就在这里的,: Need a MySQL query for selecting from a table storing key value pairs

+0

请说清楚。它没有任何意义尝试用上面的表格数据给出一个例子。 –

+0

等一下,你问一个或三个问题?您是否试图获取具有特定名称值对的所有行或行?而且这些表格并不是一团糟。他们实际上很清楚正常化。 – invertedSpear

+0

@invertedSpear我完全同意你的看法。我认为他无法清楚地传达他的信息 –

回答

0

这是假设你不会有一个给定ad_id相同ad_data_namead_data_value值重复行:

select a.* 
from ADS_DATA a 
inner join (
    select ad_id 
    from ADS_DATA 
    and (
     (ad_data_name = 'rooms' and ad_data_value = 2) 
     or (ad_data_name = 'size' and ad_data_value = 20) 
    ) 
    group by ad_id 
    having count(*) = 2 
) am on a.ad_id = am.ad_id 
where a.ad_id = 1 
0

我觉得你写回信排序的提出你自己的问题。子选择似乎适用于这里...

SELECT * FROM ADS_DATA WHERE ad_id IN (
    SELECT DISTINCT ad_id FROM ADS_DATA 
    WHERE 
     (ad_data_name = 'Foo' AND ad_data_value = 'Bar') 
    OR 
     (ad_data_name = 'Fizz' AND ad_data_value = 'Buzz') 
) 

它看起来像你的模式可以做规范化虽然。将关键字/值对存储在关系数据库中有点浪费。

+0

是的,我试过一堆posibilities,但我需要ADS_DATA行之间的严格AND,例如:rooms = 5 AND size = 45,并且存在问题。无论如何,你认为在ads_data中创建每种类型的对象的每个可能的列,只填写我需要的东西,我的意思是像一个正常的关系数据库?谢谢 – iomismo