Лучший способ поиска двух запросов и исключения строк без связи - PullRequest
0 голосов
/ 25 сентября 2011

Я работаю на веб-сайте по недвижимости и у меня есть наборы записей для собственности и для объекта, единица имеет отношение один-ко-многим с собственностью.Я пытаюсь выяснить, как лучше всего создать функцию поиска, которая будет выводить результаты на основе критериев из обоих.Поэтому, если я ищу недвижимость с местоположением в Манчестере и единицу с правом владения недвижимостью, я хотел бы исключить все свойства, у которых нет единицы с правами владения недвижимостью.

Потенциальное решение I 'мы рассмотрели создание набора записей для свойств, которые соответствуют критериям свойства, а затем создание набора записей для единиц измерения, которые соответствуют критериям модуля, и, наконец, просмотр цикла набора свойств в коде на стороне сервера и устранение любых свойств, которые не являются 't относится к любому из единиц в наборе записей единиц.Неужели вы не уверены, что это лучший способ сделать что-то, хотя вам бы хотелось услышать какие-либо предложения?

Спасибо

РЕДАКТИРОВАТЬ (добавлена ​​структура таблицы и 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

В настоящее время я использую динамически созданный оператор WHERE, добавляемый к каждому запросу MySQL, чтобы отфильтровать свойство и результаты модуля.

Ответы [ 2 ]

1 голос
/ 26 сентября 2011

Ты делаешь это немного сложнее, чем есть.Если я правильно понимаю, вы можете легко сделать это в одном запросе.Это приведет к поиску свойств, в которых есть единицы с конкретным идентификатором владения единицей:

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#">
)

Используя два запроса, а затем циклически перебирая звуки, как будто это может быть слишком медленно.

1 голос
/ 25 сентября 2011

В вашей ситуации требуется опубликованный внешний ключ в таблице свойств. Сохраните unit_id в таблице свойств и используйте объединение в своем запросе, например:

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

РЕДАКТИРОВАТЬ: Так что я только что заметил остальную часть вашего SQL. Если вам требуется сохранить таблицу отношений «многие ко многим» для отношения «единица -> свойство», то вам необходимо объединить элемент и свойство из этой таблицы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...