MySQL:从具有id的表中选择所有记录,参见schema

时间:2012-10-15 16:27:01

标签: mysql join

我不知道如何在sql中解决这个问题:

TABLE ADS:

ad_id
ad_title
ad_type_id

.... TABLE ADS_DATA:

ad_data_id
ad_id
ad_data_name
ad_data_value

好的,让我们试着让它变得简单:table 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值。 e.g:

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

好的,我如何获取ADS_DATA中的所有行和特定的ad_id(尽管名称或值的每一行)以及其中(ad_data_name = x和ad_data_value = y)AND(ad_data_name = x1和ad_data_value = y2)AND。 ..

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

更新: 这是一个例子:我试图建立一个不同类别的广告系统(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),然后只获取具有的行,例如:(在X和Y之间的house_rooms)和(在A和B之间的house_size)。在ADS_DATA列之间我需要一个'AND'而不是'OR'。你认为做出更好(也许是唯一的方法)正常“表格,只填写每个类别所需的列?

由于

更新:虽然有很多谷歌提出反对使用键/值对的建议,但我发现,尽管有性能命中,但这里有一个解决方案: Need a MySQL query for selecting from a table storing key value pairs

2 个答案:

答案 0 :(得分:0)

这假设您不会为给定的ad_data_name提供具有相同ad_data_valuead_id值的重复行:

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

答案 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')
)

看起来您的架构可以使用规范化。在关系数据库中存储键/值对是一种浪费。