连接两个表,其中一个表名称位于另一个表中

问题描述 投票:0回答:2

我正在属性表中注册各种属性。根据财产类型,使用三个新表(即公寓、别墅、土地)来存储特定数据。所以我拥有的是一个主表,其中包含属性 URL、属性类型、引用表名称(三个子表名称中的任何一个 - 公寓、别墅、土地)以及作为子表的主自动增量键的引用 id。

我尝试了三个独立的选择查询和结果的并集。缺点是结果主要来自三个表名中使用的第一个表名。

 function getMyProperty() {
        $tables = $this->getPropertyTables();
        $result = array();
        foreach ($tables as $key => $table) {
            $this->db->select('a.main_heading, a.sub_heading, a.location, a.about_property, a.property_price, a.available_from, p.property_url');
            $this->db->from('property p');
            $this->db->join($table . ' a', 'p.ref_id = a.id');
            $this->db->where('p.posted_by', $this->session->user_id);
            $this->db->where('p.ref_table', $this->db->dbprefix($table));
            $query = $this->db->get();
            $res = $query->result();
            $result = array_merge($result, $res);
        }
        return $result;
    }

数据库架构

CREATE TABLE `apartment` (
  `id` int(11) NOT NULL,
  `main_heading` varchar(256) NOT NULL,
  `sub_heading` text NOT NULL,
  `build_up_area` int(11) NOT NULL,
  `carpet_area` int(11) NOT NULL,
  `no_of_bedrooms` int(11) NOT NULL,
  `bathrooms` int(11) NOT NULL,
  `available_from` date NOT NULL,
  `furnishing` varchar(256) NOT NULL,
  `facing` varchar(100) NOT NULL,
  `flooring` varchar(256) NOT NULL,
  `parking` varchar(256) NOT NULL,
  `width_of_facing_road` varchar(100) NOT NULL,
  `property_age` int(11) NOT NULL,
  `property_price` decimal(16,2) NOT NULL DEFAULT '0.00',
  `address` text NOT NULL,
  `about_property` text NOT NULL,
  `location` varchar(256) NOT NULL,
  `amenities` text NOT NULL,
  `owner_name` varchar(256) NOT NULL,
  `owner_email` varchar(256) NOT NULL,
  `owner_phone` varchar(100) NOT NULL,
  `active` enum('Y','N') NOT NULL DEFAULT 'Y'
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT;


INSERT INTO `apartment` (`id`, `main_heading`, `sub_heading`, `build_up_area`, `carpet_area`, `no_of_bedrooms`, `bathrooms`, `available_from`, `furnishing`, `facing`, `flooring`, `parking`, `width_of_facing_road`, `property_age`, `property_price`, `address`, `about_property`, `location`, `amenities`, `owner_name`, `owner_email`, `owner_phone`, `active`) VALUES
(2, 'My Appartment', 'Place', 255, 400, 4, 4, '2019-08-08', 'semi', 'north', 'vitrified', '2', '15', 15, '15.00', 'ghkgkgk', 'jkhjkhjk', 'Kochi', '', 'Agent', '[email protected]', '9876543210', 'Y'),
(3, 'My Appartment 2', 'Test', 255, 400, 4, 4, '2019-08-08', 'semi', 'north', 'vitrified', '2', '15', 15, '15.00', 'ghkgkgk', 'jkhjkhjk', 'Kochi', '', 'Agent', '[email protected]', '9876543210', 'Y');


CREATE TABLE `land` (
  `id` int(11) NOT NULL,
  `main_heading` varchar(256) NOT NULL,
  `sub_heading` text NOT NULL,
  `plot_area` int(11) NOT NULL,
  `gated_colony` int(11) NOT NULL,
  `open_sides` int(11) NOT NULL,
  `available_from` date NOT NULL,
  `dimensions` varchar(256) NOT NULL,
  `facing` varchar(100) NOT NULL,
  `boundary_wall` varchar(256) NOT NULL,
  `parking` varchar(256) NOT NULL,
  `width_of_facing_road` varchar(100) NOT NULL,
  `property_age` int(11) NOT NULL,
  `property_price` decimal(16,2) NOT NULL DEFAULT '0.00',
  `address` text NOT NULL,
  `about_property` text NOT NULL,
  `location` varchar(256) NOT NULL,
  `owner_name` varchar(256) NOT NULL,
  `owner_email` varchar(256) NOT NULL,
  `owner_phone` varchar(100) NOT NULL,
  `active` tinyint(4) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT;

CREATE TABLE `property` (
  `property_id` int(11) NOT NULL,
  `posted_by` int(11) NOT NULL,
  `post_type` enum('RENT','SELL','LEASE') NOT NULL,
  `property_type` enum('VILLA','APARTMENT','LAND') NOT NULL,
  `property_url` varchar(50) NOT NULL,
  `ref_table` varchar(50) NOT NULL DEFAULT '',
  `ref_id` int(11) NOT NULL DEFAULT '0',
  `posted_on` date NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT;



INSERT INTO `property` (`property_id`, `posted_by`, `post_type`, `property_type`, `property_url`, `ref_table`, `ref_id`, `posted_on`) VALUES
(4, 1, 'SELL', 'VILLA', 'lyohlp', 'villa', 2, '2019-08-05'),
(5, 1, 'SELL', 'APARTMENT', 'cvbdit', 'apartment', 2, '2019-08-05'),
(6, 2, 'SELL', 'APARTMENT', 'qwerty', 'apartment', 3, '2019-08-05'),
(7, 3, 'RENT', 'VILLA', 'asdfgh', 'villa', 3, '2019-08-05');

CREATE TABLE `villa` (
  `id` int(11) NOT NULL,
  `main_heading` varchar(256) NOT NULL,
  `sub_heading` text NOT NULL,
  `build_up_area` int(11) NOT NULL,
  `carpet_area` int(11) NOT NULL,
  `no_of_bedrooms` int(11) NOT NULL,
  `bathrooms` int(11) NOT NULL,
  `available_from` date NOT NULL,
  `furnishing` varchar(256) NOT NULL,
  `facing` varchar(100) NOT NULL,
  `flooring` varchar(256) NOT NULL,
  `total_area` varchar(256) NOT NULL,
  `width_of_facing_road` varchar(100) NOT NULL,
  `property_age` int(11) NOT NULL,
  `property_price` decimal(16,2) NOT NULL DEFAULT '0.00',
  `address` text NOT NULL,
  `about_property` text NOT NULL,
  `location` varchar(256) NOT NULL,
  `amenities` text NOT NULL,
  `owner_name` varchar(256) NOT NULL,
  `owner_email` varchar(256) NOT NULL,
  `owner_phone` varchar(100) NOT NULL,
  `active` enum('Y','N') NOT NULL DEFAULT 'Y'
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT;



INSERT INTO `villa` (`id`, `main_heading`, `sub_heading`, `build_up_area`, `carpet_area`, `no_of_bedrooms`, `bathrooms`, `available_from`, `furnishing`, `facing`, `flooring`, `total_area`, `width_of_facing_road`, `property_age`, `property_price`, `address`, `about_property`, `location`, `amenities`, `owner_name`, `owner_email`, `owner_phone`, `active`) VALUES
(2, 'My Villa', 'Kakkanad', 54, 5, 4, 4, '2019-08-06', 'semi', 'west', 'not-vitrified', '111', '10', 0, '12.00', 'fhgfgh', 'ghfghf', 'Kochi', 'car_parking,water_supply,garden,fitness_center,shower,fridge', 'dfdfdf', '[email protected]', '9876543210', 'Y'),
(3, 'My Villa 2', 'Place', 54, 5, 4, 4, '2019-08-06', 'semi', 'west', 'not-vitrified', '111', '10', 0, '12.00', 'fhgfgh', 'ghfghf', 'Kochi', 'car_parking,water_supply,garden,fitness_center,shower,fridge', 'dfdfdf', '[email protected]', '9876543210', 'Y');

ALTER TABLE `apartment`
  ADD PRIMARY KEY (`id`);

ALTER TABLE `land`
  ADD PRIMARY KEY (`id`);

ALTER TABLE `property`
  ADD PRIMARY KEY (`property_id`),
  ADD KEY `ref_id` (`ref_id`);

ALTER TABLE `villa`
  ADD PRIMARY KEY (`id`);

ALTER TABLE `apartment`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=4;

ALTER TABLE `land`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;

ALTER TABLE `property`
  MODIFY `property_id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=8;

ALTER TABLE `villa`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=4;

我期望结果基于发布日期的减少,无论我提供的表格的顺序如何。

php mysql codeigniter join
2个回答
0
投票

我们知道只有一种类型可以与属性映射。

因此,数据将仅从一个表(存储该属性类型的详细信息)生成,其他表将生成 null。

如果只有一列不为空,从多列中选取数据的一个好方法是使用

CONCAT_WS
COALESCE

SELECT 
    P.property_id, P.property_url, 
    CONCAT_WS('', V.main_heading, A.main_heading, L.main_heading) AS main_heading,
    CONCAT_WS('', V.sub_heading, A.sub_heading, L.sub_heading) AS sub_heading,
    CONCAT_WS('', V.location, A.location, L.location) AS location,
    CONCAT_WS('', V.about_property, A.about_property, L.about_property) AS about_property,
    CONCAT_WS('', V.property_price, A.property_price, L.property_price) AS property_price,
    CONCAT_WS('', V.available_from, A.available_from, L.available_from) AS available_from,
    P.posted_on
FROM property P
LEFT JOIN villa V ON P.ref_table = 'villa' AND P.ref_id = V.id 
LEFT JOIN apartment A ON P.ref_table = 'apartment' AND P.ref_id = A.id
LEFT JOIN land L ON P.ref_table = 'land' AND P.ref_id = L.id
ORDER BY P.posted_on DESC;

COALESCE
的地方使用
CONCAT_WS
就像:

COALESCE(V.main_heading, A.main_heading, L.main_heading) AS main_heading

参考:MySQL 函数:COALESCEMySQL 函数:CONCAT_WS


0
投票

您可以在 CI 中集成以下查询,而不是在 php 中循环。它提供单组数组。

SELECT 
  a.*,
  b.id,
  c.id,
  d.id 
FROM
  `property` AS a 
  LEFT JOIN `apartment` AS b 
    ON a.`ref_id` = b.id 
    AND a.`ref_table` = 'apartment' 
  LEFT JOIN `land` AS c 
    ON a.`ref_id` = c.id 
    AND a.`ref_table` = 'land' 
  LEFT JOIN `villa` AS d 
    ON a.`ref_id` = d.id 
    AND a.`ref_table` = 'villa' 
ORDER BY a.`posted_by` DESC ;

这里,连接

constant table name
各自的表和其他字段将返回null。这些条件可以在PHP代码中映射。

Note : add necessary columns in select what you needed.

也添加此条件:

$this->db->where('p.posted_by', $this->session->user_id);
在查询中

© www.soinside.com 2019 - 2024. All rights reserved.