2011-09-25 7 views
0

私はプロパティのWebサイトで作業しており、プロパティのレコードセットを持っていて、単位はプロパティと1対多の関係を持っています。私が理解しようとしているのは、両方の基準に基づいて結果を出力する検索機能を最適に作成する方法です。だから私がマンチェスターの場所とフリーホールド保有期間のある不動産を検索した場合、私はフリーホールドの保有期間を持たないすべての不動産を排除したいと考えています。2つのクエリを検索し、関係のない行を削除する最も良い方法

私が考えた潜在的な解決策は、プロパティ基準に一致するプロパティのレコードセットを作成し、ユニット基準に一致するユニットのユニットレコードセットを作成し、最後にserver-ユニットレコードセットのどのユニットにも関連していないプロパティを削除します。しかし、これが最善の方法であるかどうかは確かに分かりませんが、提案を聞いてみたいと思うでしょうか?

おかげ

EDIT(追加されたテーブル構造とMySQL):

-- 
-- Table structure for table `property` 
-- 

CREATE TABLE IF NOT EXISTS `property` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `name` text NOT NULL, 
    `street` text NOT NULL, 
    `town` text NOT NULL, 
    `postcode` text NOT NULL, 
    `description` longtext NOT NULL, 
    `team_member` varchar(255) NOT NULL DEFAULT '', 
    `pdf` text NOT NULL, 
    `default_image_id` int(11) DEFAULT NULL, 
    `virtual_tour_link` text NOT NULL, 
    `date` date NOT NULL DEFAULT '0000-00-00', 
    `archive` int(11) NOT NULL DEFAULT '0', 
    PRIMARY KEY (`id`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='' AUTO_INCREMENT=13 ; 

-- 
-- Table structure for table `unit` 
-- 

CREATE TABLE IF NOT EXISTS `unit` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `name` text NOT NULL, 
    `description` text NOT NULL, 
    `size_sq_ft` int(11) DEFAULT NULL, 
    `size_acres` float DEFAULT NULL, 
    `price` float DEFAULT NULL, 
    `rental_price` float DEFAULT NULL, 
    `on_application` tinyint(1) DEFAULT NULL, 
    UNIQUE KEY `id` (`id`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Stores data for property units' AUTO_INCREMENT=5; 

-- 
-- Table structure for table `property_to_unit` 
-- 

CREATE TABLE IF NOT EXISTS `property_to_unit` (
    `property_id` int(11) NOT NULL, 
    `unit_id` int(11) NOT NULL 
) ENGINE=MyISAM DEFAULT CHARSET=utf8; 


-- 
-- MySQL which produces list of properties 
-- 

SELECT 
    P.id AS id, 
    P.name AS name, 
    P.street AS street, 
    P.town AS town, 
    P.postcode AS postcode, 
    P.description AS description, 
    P.team_member AS team_member, 
    P.pdf AS pdf, 
    P.virtual_tour_link AS virtual_tour_link, 
    P.date AS date, 
    P.archive AS archive, 
    PI.name as image, 
    P2.image_ids as image_ids, 
    L2.location_ids as location_ids, 
    U2.unit_ids as unit_ids 

FROM property P 

-- Get default image and join using property id 

LEFT JOIN property_image PI ON PI.id = P.default_image_id 

-- Create a list of image_ids from property_image and 
-- property_to_property_image tables then join using property_id 

LEFT JOIN (

    SELECT 
     property_id, 
     GROUP_CONCAT(CAST(id AS CHAR)) as image_ids 
    FROM property_to_property_image PTPI 
    LEFT JOIN property_image PI ON PI.id = PTPI.property_image_id 
    GROUP BY property_id 

) P2 ON P2.property_id = P.id 

-- Create a list of locations from property_location table 
-- and join using property_id 

LEFT JOIN (
    SELECT 
     property_id, 
     property_location_id, 
     GROUP_CONCAT(CAST(property_location.id AS CHAR)) AS location_ids 
    FROM property_to_property_location 
    INNER JOIN property_location ON property_location.id = property_to_property_location.property_location_id 
    GROUP BY property_id 
) L2 ON L2.property_id = P.id 

-- Create a list of units from unit table 
-- and join using property_id 

LEFT JOIN (
    SELECT 
     property_id, 
     unit_id, 
     GROUP_CONCAT(CAST(unit_id AS CHAR)) AS unit_ids 
    FROM property_to_unit 
    INNER JOIN unit ON unit.id = property_to_unit.unit_id 
    GROUP BY property_id 
) U2 ON U2.property_id = P.id 

-- 
-- MySQL which produces list of units 
-- 

SELECT 
id, 
name, 
description, 
size_sq_ft, 
size_acres, 
price, 
rental_price, 
on_application, 
tenure_ids, 
tenure_names, 
type_ids, 
type_names 
FROM unit AS U 

-- join tenure ids and names 

LEFT JOIN (

    SELECT 
     unit_id, 
     GROUP_CONCAT(CAST(UT.id AS CHAR)) AS tenure_ids, 
     GROUP_CONCAT(UT.name) AS tenure_names 
    FROM unit_to_unit_tenure UTUT 
    INNER JOIN unit_tenure UT ON UT.id = UTUT.unit_tenure_id 
    GROUP BY unit_id 

) UT ON UT.unit_id = U.id 

-- join type ids and names 

LEFT JOIN (

    SELECT 
     unit_id, 
     GROUP_CONCAT(CAST(UTYPE.id AS CHAR)) AS type_ids, 
     GROUP_CONCAT(UTYPE.name) AS type_names 
    FROM unit_to_unit_type UTUT 
    INNER JOIN unit_type UTYPE ON UTYPE.id = UTUT.unit_type_id 
    GROUP BY unit_id 

) UTYPE ON UTYPE.unit_id = U.id 

WHERE 0=0 

私は現在、財産やユニットの結果をフィルタリングするために、各MySQLのクエリに追加動的に作成WHEREステートメントを使用しています。

+1

これは、 'JOIN'を使って行うことができます - あなたはいくつかのSQLとテーブル構造を表示する必要があります... – Yahia

+0

アドバイスYahiaのおかげで。 –

答えて

1

あなたはそれを少し複雑にしています。私が正しく理解していれば、簡単に1回のクエリでこれを行うことができます。これはparticlar単位の任期IDを持つユニットを持つプロパティを検索します:

select * 
from property p 
where p.id in (
    select pu.property_id 
    from property_to_unit pu 
     inner join unit u ON pu.unit_id = u.id 
     inner join unit_to_unit_tenure uut ON u.id = uut.unit_id 
    where uut.id = <cfqueryparam value="#uutid#"> 
) 

2つのクエリを使用して、クロスチェックに至るループそれは遅い犬かもしれないように聞こえます。

+0

あなたのお返事ありがとうDavid、これははるかに意味がある、私はこれを行って、どのように公正を参照してください。 –

+0

これを今までに十分にテストして、うまくいきました。 –

1

状況によっては、転記された外部キーがプロパティテーブルに必要です。プロパティテーブルにunit_idを保存し、のようなクエリで結合を使用:

select * from property p, unit u 
where p.unit_id = u.id 
and p.town = .... 

EDIT:をだから私は自分のSQLの残りの部分に気づきました。ユニット - >プロパティー関係の多対多関係表を保持する必要がある場合は、その表のユニットとプロパティーを結合する必要があります。

+0

あなたのお返事ありがとうPhil、実際には多対多の関係テーブルは必要ないことに気付きました。本当に必要なのは単位テーブルのproperty_idの外部キーですが、この問題のためにはそれを続けます。また、Davidのソリューションがうまくいくように見えます。 –

関連する問題