-
-
Save rockymontana/3017478 to your computer and use it in GitHub Desktop.
-- | |
-- Table structure for table `apartments` | |
-- | |
CREATE TABLE IF NOT EXISTS `apartments` ( | |
`id` int(10) unsigned NOT NULL AUTO_INCREMENT, | |
`name` varchar(8) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL, | |
`rooms` varchar(2) COLLATE utf8_swedish_ci NOT NULL, | |
`floor` int(2) NOT NULL, | |
`m2` int(5) NOT NULL, | |
`address` varchar(64) COLLATE utf8_swedish_ci NOT NULL, | |
`house` varchar(16) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL, | |
`available` tinyint(1) NOT NULL, | |
`date_of_arrival` date DEFAULT '0000-00-00', | |
`rent` int(5) NOT NULL COMMENT 'monthly cost', | |
`description` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL, | |
PRIMARY KEY (`id`) | |
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_swedish_ci AUTO_INCREMENT=6 ; | |
-- | |
-- Dumping data for table `apartments` | |
-- | |
INSERT INTO `apartments` (`id`, `name`, `rooms`, `floor`, `m2`, `address`, `house`, `available`, `date_of_arrival`, `rent`, `description`) VALUES | |
(1, '0102', '3', 1, 78, 'Kringelvägen 2B', 'Draken', 0, NULL, 5700, 'Mucket fein leilighet!!'), | |
(3, '0101', '3', 1, 79, 'Kringelvägen 2B', 'Draken', 0, NULL, 5700, 'En likadant lägenhet!'), | |
(4, '0103', '3', 2, 79, 'Kringelvägen 2B', 'Draken', 0, NULL, 5900, 'Ännu en likadant lägenhet!'), | |
(5, '0104', '3', 2, 79, 'Kringelvägen 2B', 'Draken', 0, NULL, 5900, 'Ännu en likadant lägenhet!'); | |
-- -------------------------------------------------------- | |
-- | |
-- Table structure for table `apartment_fields` | |
-- | |
CREATE TABLE IF NOT EXISTS `apartment_fields` ( | |
`id` int(11) NOT NULL AUTO_INCREMENT, | |
`name` varchar(128) COLLATE utf8_bin NOT NULL, | |
PRIMARY KEY (`id`), | |
UNIQUE KEY `name` (`name`) | |
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=3 ; | |
-- | |
-- Dumping data for table `apartment_fields` | |
-- | |
INSERT INTO `apartment_fields` (`id`, `name`) VALUES | |
(2, 'area'), | |
(1, 'district'); | |
-- -------------------------------------------------------- | |
-- | |
-- Table structure for table `apartment_field_data` | |
-- | |
CREATE TABLE IF NOT EXISTS `apartment_field_data` ( | |
`apartment_field_id` int(11) NOT NULL, | |
`apartment_id` int(11) unsigned NOT NULL, | |
`value` varchar(128) NOT NULL, | |
KEY `apartment_id` (`apartment_id`), | |
KEY `apartment_field_id` (`apartment_field_id`) | |
) ENGINE=InnoDB DEFAULT CHARSET=utf8; | |
-- | |
-- Dumping data for table `apartment_field_data` | |
-- | |
INSERT INTO `apartment_field_data` (`apartment_field_id`, `apartment_id`, `value`) VALUES | |
(1, 1, 'Mjärden'), | |
(2, 1, 'Maria'), | |
(1, 3, 'Mjärden'), | |
(2, 3, 'Maria'), | |
(1, 4, 'Mjärden'), | |
(2, 4, 'Maria'), | |
(1, 5, 'Mjärden'), | |
(2, 5, 'Maria'); | |
-- | |
-- Constraints for dumped tables | |
-- | |
-- | |
-- Constraints for table `apartment_field_data` | |
-- | |
ALTER TABLE `apartment_field_data` | |
ADD CONSTRAINT `apartment_field_data_ibfk_1` FOREIGN KEY (`apartment_field_id`) REFERENCES `apartment_fields` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, | |
ADD CONSTRAINT `apartment_field_data_ibfk_2` FOREIGN KEY (`apartment_id`) REFERENCES `apartments` (`id`) ON DELETE CASCADE ON UPDATE CASCADE; |
SELECT A.*,AFD.apartment_id as apartment_id, AF.name as field_name,AFD.value
FROM apartments AS A, apartment_field_data as AFD
INNER JOIN apartment_fields AS AF ON
AFD.apartment_field_id = AF.id WHERE apartment_id = A.id;
mysql> SELECT A.*,AFD.apartment_id as apartment_id, AF.name as field_name,AFD.value
-> FROM apartments AS A, apartment_field_data as AFD
-> INNER JOIN apartment_fields AS AF ON
-> AFD.apartment_field_id = AF.id WHERE apartment_id = A.id
-> ;
+----+------+-------+-------+----+----------------+--------+-----------+-----------------+------+--------------------------+--------------+------------+--------+
| id | name | rooms | floor | m2 | address | house | available | date_of_arrival | rent | description | apartment_id | field_name | value |
+----+------+-------+-------+----+----------------+--------+-----------+-----------------+------+--------------------------+--------------+------------+--------+
| 1 | 0102 | 3 | 1 | 78 | Kringelvgen 2B | Draken | 0 | NULL | 5700 | Mucket fein leilighet!! | 1 | district | Mjrden |
| 1 | 0102 | 3 | 1 | 78 | Kringelvgen 2B | Draken | 0 | NULL | 5700 | Mucket fein leilighet!! | 1 | area | Maria |
| 3 | 0101 | 3 | 1 | 79 | Kringelvgen 2B | Draken | 0 | NULL | 5700 | En likadant lgenhet! | 3 | district | Mjrden |
| 3 | 0101 | 3 | 1 | 79 | Kringelvgen 2B | Draken | 0 | NULL | 5700 | En likadant lgenhet! | 3 | area | Maria |
| 4 | 0103 | 3 | 2 | 79 | Kringelvgen 2B | Draken | 0 | NULL | 5900 | nnu en likadant lgenhet! | 4 | district | Mjrden |
| 4 | 0103 | 3 | 2 | 79 | Kringelvgen 2B | Draken | 0 | NULL | 5900 | nnu en likadant lgenhet! | 4 | area | Maria |
| 5 | 0104 | 3 | 2 | 79 | Kringelvgen 2B | Draken | 0 | NULL | 5900 | nnu en likadant lgenhet! | 5 | district | Mjrden |
| 5 | 0104 | 3 | 2 | 79 | Kringelvgen 2B | Draken | 0 | NULL | 5900 | nnu en likadant lgenhet! | 5 | area | Maria |
+----+------+-------+-------+----+----------------+--------+-----------+-----------------+------+--------------------------+--------------+------------+--------+
8 rows in set (0.00 sec)
$this->data = $this->pdo->query('SELECT * FROM apartments WHERE id = '.$id)->fetch(PDO::FETCH_ASSOC);
$field_data = $this->pdo->query('SELECT AF.name as field_name,AFD.value FROM apartment_field_data as AFD INNER JOIN apartment_fields AS AF ON AFD.apartment_field_id = AF.id WHERE apartment_id = '.$id)->fetchAll(PDO::FETCH_ASSOC);
foreach ($field_data as $result)
foreach ($result as $row )
$this->data[$result['field_name']] = $row;
foreach($this->data as $key => $value)
if (is_null($value)) unset($this->data[$key]);
select
apartment_id,
group_concat(if(name = 'district', value, null)) as district,
group_concat(if(name = 'area', value, null)) as area
from apartment_field_data as afd
inner join apartment_fields as af
on afd.apartment_field_id = af.id
group by apartment_id;
mysql> select
-> apartment_id,
-> group_concat(if(name = 'district', value, null)) as district,
-> group_concat(if(name = 'area', value, null)) as area
-> from apartment_field_data as afd
-> inner join apartment_fields as af
-> on afd.apartment_field_id = af.id
-> group by apartment_id;
+--------------+----------+-------+
| apartment_id | district | area |
+--------------+----------+-------+
| 1 | Mjrden | Maria |
| 3 | Mjrden | Maria |
| 4 | Mjrden | Maria |
| 5 | Mjrden | Maria |
+--------------+----------+-------+
4 rows in set (0.01 sec)
Kudos till lillem4n ( https://github.com/lillem4n ) för denna lösningen:
public static function get_all($q = FALSE, $start = 0, $limit = 100, $order_by = FALSE, $field_search = FALSE)
{
$pdo = Kohana_pdo::instance();
$data_fields = array();
$sql = 'SELECT apartments.*,';
foreach ($pdo->query('SELECT id, name FROM apartment_fields ORDER BY name;') as $row)
{
$sql .= '(SELECT GROUP_CONCAT(value SEPARATOR \', \') FROM apartment_field_data WHERE apartment_field_id = '.$row['id'].' AND apartment_id = apartments.id ORDER BY value) AS '.Mysql::quote_identifier($row['name']).',';
$data_fields[$row['id']] = $row['name'];
}
$sql = substr($sql, 0, strlen($sql) -1);
$sql .= ' FROM apartments LEFT JOIN apartment_field_data AS apartments_data ON apartments_data.apartment_id = apartments.id';
$sql .= ' WHERE 1 = 1';
if (is_string($q) || ! empty($field_search)) $sql .= ' AND (';
if (is_string($q)) $sql .= 'apartment.name LIKE '.$pdo->quote('%'.$q.'%').' OR apartment_field_data.value LIKE '.$pdo->quote('%'.$q.'%').' OR';
if ( ! empty($field_search))
{
foreach ($field_search as $field => $search_string)
{
if ($field_id = array_search($field, $data_fields))
{
$sql .= 'apartments.id IN (SELECT apartment_id FROM apartment_field_data WHERE apartment_field_id = '.$field_id.' AND value LIKE '.$pdo->quote('%'.$search_string.'%').') OR';
}
}
}
if (is_string($q) || ! empty($field_search)) $sql = substr($sql, 0, strlen($sql) - 3).')';
$sql .= ' GROUP BY apartments.id';
if ( ! empty($order_by))
{
if (is_string($order_by) && in_array($order_by, $data_fields))
$sql .= ' ORDER BY IF(ISNULL('.Mysql::quote_identifier($order_by).'),1,0),'.Mysql::quote_identifier($order_by);
elseif ($order_by == 'value')
$sql .= ' ORDER BY value';
elseif (is_array($order_by))
{
$order_by_set = FALSE;
foreach ($order_by as $field => $order)
{
if (in_array($field, $data_fields) || $field == 'name')
{
if ( ! $order_by_set)
{
$sql .= ' ORDER BY ';
$order_by_set = TRUE;
}
if ($field == 'name')
$sql .= 'name';
else
$sql .= 'IF(ISNULL('.Mysql::quote_identifier($field).'),1,0),'.Mysql::quote_identifier($field);
if ($order == 'ASC' || $order == 'DESC') $sql .= ' '.$order;
$sql .= ',';
}
}
if ($order_by_set) $sql = substr($sql, 0, strlen($sql) - 1);
}
}
if ($limit)
{
if ($start) $sql .= ' LIMIT '.$start.','.$limit;
else $sql .= ' LIMIT '.$limit;
}
return $pdo->query($sql)->fetchAll(PDO::FETCH_ASSOC);
}
result:
mysql> SELECT A.*,AFD.apartment_id as apartment_id, AF.name as field_name,AFD.value FROM apartments AS A, apartment_field_data as AFD INNER JOIN apartment_fields AS AF ON AFD.apartment_field_id = AF.id WHERE apartment_id = A.id
-> ;
+----+------+-------+-------+----+-----------------+--------+-----------+-----------------+------+----------------------------+--------------+------------+---------+
| id | name | rooms | floor | m2 | address | house | available | date_of_arrival | rent | description | apartment_id | field_name | value |
+----+------+-------+-------+----+-----------------+--------+-----------+-----------------+------+----------------------------+--------------+------------+---------+
| 1 | 0102 | 3 | 1 | 78 | Kringelv�gen 2B | Draken | 0 | NULL | 5700 | Mucket fein leilighet!! | 1 | area | Maria |
| 3 | 0101 | 3 | 1 | 79 | Kringelv�gen 2B | Draken | 0 | NULL | 5700 | En likadant l�genhet! | 3 | area | Maria |
| 4 | 0103 | 3 | 2 | 79 | Kringelv�gen 2B | Draken | 0 | NULL | 5900 | �nnu en likadant l�genhet! | 4 | area | Maria |
| 5 | 0104 | 3 | 2 | 79 | Kringelv�gen 2B | Draken | 0 | NULL | 5900 | �nnu en likadant l�genhet! | 5 | area | Maria |
| 1 | 0102 | 3 | 1 | 78 | Kringelv�gen 2B | Draken | 0 | NULL | 5700 | Mucket fein leilighet!! | 1 | district | Mj�rden |
| 3 | 0101 | 3 | 1 | 79 | Kringelv�gen 2B | Draken | 0 | NULL | 5700 | En likadant l�genhet! | 3 | district | Mj�rden |
| 4 | 0103 | 3 | 2 | 79 | Kringelv�gen 2B | Draken | 0 | NULL | 5900 | �nnu en likadant l�genhet! | 4 | district | Mj�rden |
| 5 | 0104 | 3 | 2 | 79 | Kringelv�gen 2B | Draken | 0 | NULL | 5900 | �nnu en likadant l�genhet! | 5 | district | Mj�rden |
+----+------+-------+-------+----+-----------------+--------+-----------+-----------------+------+----------------------------+--------------+------------+---------+