Merge result after query with JOIN clause in Mysql - php

I have two table like this:
Product
id | title
-------------------------------
1 | Skirt
2 | Pants
Product_thumbnail
id | product_id | image
-------------------------------
1 | 1 | pant.jpg
2 | 1 | shoes.png
When I want to get product with the thumbnail, I query like this:
SELECT p.*, pt.image FROM product p
LEFT JOIN product_thumbnail pt ON pt.product_id = p.id;
The output I expected
[0]=> [
[id] => 1
[image] =>
[
[0] => pant.jpg
[1] => shoes.jpg
]
]
[1]=> [
[id] => 2
[image] => null
]
But the real output
[0]=> [
id => 1
image => pant.jpg
]
[1]=> [
id => 1
image => shoes.jpg
]
[2]=> [
id => 2
image => shoes.jpg
]
As you see, there is 2 element duplicate, so I need to merge it by hand, is there any way to achieve this more easy? Because my table have many tables relate together more than this, I'm using PHP, I use array_merge_recursive() to merge them but if do like that I get duplicate value in each field, like this:
[0]=> [
[id] =>
[
[0] => 1
[1] => 1
]
[image] =>
[
[0] => pant.jpg
[1] => shoes.jpg
]
]
It's not what I want, can anyone give me an idea?

Consider the following. The code could I'm sure be written more economically, but hopefully you get the idea...
<?php
/*
DROP TABLE IF EXISTS product;
CREATE TABLE product
(id SERIAL PRIMARY KEY
,title VARCHAR(12) NOT NULL UNIQUE
);
INSERT INTO product VALUES
(1,'Hat'),
(2,'Shoe');
DROP TABLE IF EXISTS product_thumbnail;
CREATE TABLE product_thumbnail
(id SERIAL PRIMARY KEY
,product_id INT NOT NULL
,image VARCHAR(12) NOT NULL UNIQUE
);
INSERT INTO product_thumbnail VALUES
(1,1,'sombrero.jpg'),
(2,1,'stetson.png');
SELECT p.id
, p.title
, t.image
FROM product p
LEFT
JOIN product_thumbnail t
ON t.product_id = p.id;
+----+-------+--------------+
| id | title | image |
+----+-------+--------------+
| 1 | Hat | sombrero.jpg |
| 1 | Hat | stetson.png |
| 2 | Shoe | NULL |
+----+-------+--------------+
*/
require('path/to/connection/stateme.nts');
$query = "
SELECT p.id
, p.title
, t.image
FROM product p
LEFT
JOIN product_thumbnail t
ON t.product_id = p.id;
";
$result = mysqli_query($db,$query);
$old_array = array();
while($row = mysqli_fetch_assoc($result)){
$old_array[] = $row;
}
$new_array = array();
foreach ($old_array as $row) {
$new_array[$row['id']]['title'] = $row['title'];
$new_array[$row['id']]['image'][] = $row['image'];
}
$new_array = array_values($new_array); // reindex
print_r($new_array);
?>
Outputs
Array
(
[0] => Array
(
[title] => Hat
[image] => Array
(
[0] => sombrero.jpg
[1] => stetson.png
)
)
[1] => Array
(
[title] => Shoe
[image] => Array
(
[0] =>
)
)
)

MySQL doesn't support arrays, but you can aggregate the data into a string:
SELECT p.*, GROUP_CONCAT(pt.image) as images
FROM product p LEFT JOIN
product_thumbnail pt
ON pt.product_id = p.id
GROUP BY p.id;
Note that aggregating only by the id and selecting p.* is allowed and even standard SQL -- assuming that id is a primary key or declared to be unique. This is the one situation when this syntax is permitted.

Related

Consolidate Query Results into Single Index

I have a table (usermeta - 2nd below) that is causing my trouble. I need to get 2 values from this table in 1 query and return the results in a single array index.
One table (users) contains the following:
ID | user_email | display_name |
-----+------------------+---------------|
8 | bob#bobjones.com | bob jones |
9 | rob#robsmith.com | rob smith |
Another table (usermeta) contains:
user_id | meta_key | meta_value |
----------+--------------+--------------|
8 | phone_number | 4441234433 |
8 | rep_id | abc123 |
9 | phone_number | 5552323322 |
9 | rep_id | xyz456 |
My SQL query:
function get_this() {
global $db;
$get = $db->get_results("
SELECT
um.meta_key, um.meta_value, um.user_id, user.user_email, user.display_name
FROM
users as user
LEFT OUTER JOIN
usermeta as um
ON
user.ID = um.user_id
WHERE
um.meta_key='rep_id'
OR
um.meta_key='phone_number'
");
return $get;
}
Calling the function: $foo = get_this(); returns this array:
Array
(
[0] => stdClass Object
(
[meta_key] => phone_number
[meta_value] => 4441234433
[user_id] => 8
[user_email] => bob#bobjones.com
[display_name] => bob jones
)
[1] => stdClass Object
(
[meta_key] => rep_id
[meta_value] => abc123
[user_id] => 8
[user_email] => bob#bobjones.com
[display_name] => bob jones
)
[2] => stdClass Object
(
[meta_key] => phone_number
[meta_value] => 5552323322
[user_id] => 9
[user_email] => rob#robsmith.com
[display_name] => rob smith
)
[3] => stdClass Object
(
[meta_key] => rep_id
[meta_value] => xyz456
[user_id] => 9
[user_email] => rob#robsmith.com
[display_name] => rob smith
)
)
The problem I am having is in consolidating the data based on user_id. I'd like to return an array that includes both their phone number AND their rep id along with their user_id, user_email and display_name in one index so I can print something like: bob jones, bob#bobjones.com, 4441234433, abc123
I clearly do not know what question to ask as I've spent 3 days now researching this site and the Internet and trying various combinations of CASE, AND, OR, WHERE, UNION, GROUP etc. to no avail. I am happy to manage this on the PHP end but have failed in that department as well.
You could put two different meta values on the same row of result by joining twice to the meta table:
SELECT user.user_id, user.user_email, user.display_name,
um1.meta_value AS `rep_id`,
um2.meta_value AS `phone_number`
FROM users AS user
LEFT OUTER JOIN usermeta AS um1
ON user.ID = um1.user_id AND um1.meta_key = 'rep_id'
LEFT OUTER JOIN usermeta AS um2
ON user.ID = um2.user_id AND um2.meta_key = 'phone_number'

php list and select data using join tables

I have this database table structure for posts, categories and post_categories
posts:
| id | title | details
| 1 | test | test details
categories:
| id | name | parent_id
| 1 | cat one | 0
| 2 | cat two | 0
| 3 | cat three | 0
post_categories
| category_id | post_id
| 1 | 1
| 2 | 1
I insert multiple categories using input checkbox for each post in post_categories table. Now in update page(domain.com/admin/posts/1/edit) i need to show categories list and checked input checkbox.can i generate this output using join two table(categories and post_categories) Or I need to separate two query(first from post_category table and second from categories table) like this output?! (my choice is join method so how to generate use join method?)
<input type="checkbox" value="1" checked> cat one
<input type="checkbox" value="2" checked> cat two
<input type="checkbox" value="3"> cat three //unchecked (not in post_categories table)
update:
for list categories query:
$query = $this->db->table('categories')
->select('id, name, parent_id')
->get()
->getResultObject();
data in print_r:
Array
(
[0] => stdClass Object
(
[id] => 1
[name] => cat one
[parent_id] => 0
)
[1] => stdClass Object
(
[id] => 2
[name] => cat two
[parent_id] => 0
)
[2] => stdClass Object
(
[id] => 3
[name] => cat three
[parent_id] => 0
)
[3] => stdClass Object
(
[id] => 4
[name] => cat4
[parent_id] => 2
)
[4] => stdClass Object
(
[id] => 5
[name] => cat5
[parent_id] => 0
)
[5] => stdClass Object
(
[id] => 6
[name] => cat6
[parent_id] => 0
)
)
after join:
$query = $this->db->table('categories')
->select('id, name, parent_id')
->join('post_categories', 'post_categories.category_id = id','left outer')
->where('post_categories.post_id', $id)
->get()
->getResultObject();
and data is:
Array
(
[0] => stdClass Object
(
[id] => 1
[name] => cat one
[parent_id] => 0
)
[1] => stdClass Object
(
[id] => 4
[name] => cat two
[parent_id] => 2
)
)
result after join is false.
You can do this with one query but for this, you need one extra column in query for checking category is using or not.
SELECT id, name, if(pc.cat_id IS NULL,0,1) as `value` from categories as ct LEFT JOIN post_categories as pc on pc.cat_id = ct.id
demo link
I hope this query will fulfill your requirements.
If you need more detail about this you can visit this StackOverflow thread
MySQL Join and create new column value
You can run below query to get the categories selected:
select post_categories.category_id from posts
left join post_categories on post_categories.post_id=posts.id
left join categories on post_categories.category_id=categories.id;
get these ids to an array and within your category loop check if the ids are in array and make them checked.
quite easy !

How to execute that in 1 query?

I have 2 tables customer and orders:
customers:
| custID | Name | Age |
|--------|-------|-----|
| 1 | Peter | 23 |
| 2 | Julie | 34 |
| 3 | Tom | 45 |
orders:
| custID | product | color |
|--------|---------|-------|
| 1 | shirt | blue |
| 1 | jacket | black |
| 2 | jacket | green |
| 3 | hat | grey |
| 3 | shirt | white |
I now want to get all customers and their orders, ordered as a list. So something like that:
Array
(
[0] => Array
(
[ID] => 1
[name] => Peter
[age] => 23
[orders] => Array
(
[0] => Array
(
[product] => shirt
[color] => blue
)
[1] => Array
(
[product] => jacket
[color] => black
)
)
)
[1] => Array
(
[ID] => 2
[name] => Julie
[age] => 34
[orders] => Array
(
[0] => Array
(
[product] => jacket
[color] => green
)
)
)
[2] => Array
(
[ID] => 3
[name] => Tom
[age] => 45
[orders] => Array
(
[0] => Array
(
[product] => hat
[color] => grey
)
[1] => Array
(
[product] => shirt
[color] => white
)
)
)
)
When I do:
SELECT name, age, product, color
FROM `customers`, `orders`
where `customers`.`id` = `orders`.id
group by name
I get:
| name | age | product | color |
|-------|-----|---------|-------|
| Peter | 23 | jacket | green |
| Julie | 34 | shirt | blue |
| Tom | 45 | hat | grey |
Is this even possible with only one query?
You could simply make the query below:
SELECT *
FROM customers
JOIN orders
USING custID
GROUP BY Name
ORDER BY custID ASC;
A couple of steps here...
First, you should run the following query:
SELECT
`customers`.`id`,
`customers`.`name`,
`customers`.`age`,
`orders`.`product`,
`orders`.`color`
FROM `customers`, `orders`
where `customers`.`id` = `orders`.`id`
order by `customers`.`id`
Which should give you de-normalized tabular data that looks something like this:
$array = array(
array("id" => 1, "name" => "Peter", "age" => 23, "product" => "shirt", "color" => "blue"),
array("id" => 1, "name" => "Peter", "age" => 23, "product" => "jacket", "color" => "black"),
array("id" => 2, "name" => "Julie", "age" => 34, "product" => "jacket", "color" => "green"),
array("id" => 3, "name" => "Tom", "age" => 45, "product" => "hat", "color" => "grey"),
array("id" => 3, "name" => "Tom", "age" => 45, "product" => "shirt", "color" => "white")
);
You can then transform the that data into your desired format as follows:
$transformed = array();
$i = 0;
while ($i < count($array)) {
$id = $array[$i]["id"];
$name = $array[$i]["name"];
$age = $array[$i]["age"];
$products = array();
while ($i < count($array) && $id == $array[$i]["id"]) {
array_push($products, array("product" => $array[$i]["product"], "color" => $array[$i]["color"]));
$i++;
}
array_push($transformed, array("id" => $id, "name" => $name, "age" => $age, "products" => $products));
}
http://sandbox.onlinephpfunctions.com/code/6fe856e1f71f699e84215b6f66d25589f71e255e
i think you should user INNER JOIN:
SELECT * FROM customers AS c INNER JOIN orders AS o ON c.custID = o.custID GROUP BY c.custID ORDER BY c.custID ASC;
There is no point in trying to achieve the desired outcome with single query. With the first query get the list of customers. Then perform a second query, which will load all the orders for the customers from the first query. And in a loop match orders to respective customers.
EDIT: something like this
$result = [];
$customers = $pdo->query("SELECT * FROM `customers`")->fetchAll();
foreach ($customers as $c) {
$result[$c['id']] = $c;
}
$orders = $pdo->query("SELECT * FROM `orders` WHERE `custID` IN (".implode(', ', array_keys($result).")");
foreach ($orders as $o) {
if (!isset($result[$o['custId']]['orders']))
$result[$o['custId']]['orders'] = [];
$result[$o['custId']]['orders'][] = $o;
}
Your sql SELECT name, age, product, color FROMcustomers,orderswherecustomers.id=orders.id group by name is fine, just add the customer id and order id also in the sql. Then, in PHP, as you iterate the result set, populate the customer info first (id, name, age) with customer id as the key and name, age as value as an array. Likewise, populate the order for that customer in the key 'orders' with the order id as key and value as an array (product, color).
Once you have the array populated, iterate over that array and keep putting things into a new array since the output you want is an array with sequential keys (0, 1, 2 etc) instead of customer id.
$initialList = array();
while($row = $result->fetch_assoc()) {
if(!array_key_exists($row['customer_id'], $initialList)) {
$initialList[$row['customer_id']] = array(
'name' => $row['name'],
'age' => $row['age'],
'orders' => array()
);
}
$initialList[$row['customer_id']]['orders'][] = array(
'product' => $row['product'],
'color' => $row['color']
);
}
$finalList = array();
foreach($initialList as $customerId => $customer) {
$customer['ID'] = $customerId;
$finalList[] = $customer;
}
//to print and check the array
print_r($finalList);
try this:
SELECT c.custID,c.name, c.age, group_concat(CONCAT_WS(':',o.product,o.color)SEPARATOR ',') as productos
FROM customers AS c
INNER JOIN orders AS o ON c.custID = o.custID
GROUP BY c.custID;
You just have to parse the products.
$array=array();
while($r = $res->fetch_assoc()) {
$id=$row['custID'];
$name=$row['name'];
$age=$row['age'];
$productos=$row['productos'];
$productsSeparats = explode(',',$productos);
$orders=array();
foreach ($productsSeparats as $value) {
$ar=explode(':',$value);
array_push($orders, array("product" => $ar[0], "color" => $ar[1]));
}
array_push($array, array("id" => $id, "name" => $name, "age" => $age, "orders" => $orders));
}

PHP SQL left join fetch all

I have 3 mysql tables from where I am trying to fetch data
Table: list
list_id | name | description
-------------------------------------
1234 | name1 | sample description1
1235 | name2 | sample description2
Table: list_to_category
id | list_id | category_id
--------------------------------
1 | 1234 | 1
2 | 1234 | 2
3 | 1234 | 3
4 | 1235 | 2
5 | 1235 | 3
And table: category
id | title | parent_id
--------------------------------
1 | Category 1 | 0
2 | Category 2 | 0
3 | Category 3 | 0
And from PHP SQL query I want to fetch data like below
1. name1 - category 1, category 2, category 3
2. name2 - category 2, category 3
I tried below query
SELECT list.name, category.title FROM list
LEFT JOIN list_to_category
ON list.id = list_to_category.list_id
LEFT JOIN category
ON list_to_category.id = category.id
This gives me only single category name assigned to a list like this
1. name1 - category 1
2. name2 - category 2
Is it possible in single query?
You can use GROUP_CONCAT for this:
select
l.list_id,
l.name,
group_concat(distinct c.title) categories
from list l
left join list_to_category lc
on l.list_id = lc.list_id
left join category c
on lc.category_id = c.id
group by l.list_id
You can try this solution.
select l.list_id, l.name, (select group_concat(c.title) from list_to_category ltc JOIN category c ON c.id=ltc.category_id where ltc.list_id=l.id) from list l
Hope this will help you!!!
Use GROUP_CONCAT for group by "name" to fetch result :
SELECT L.name, GROUP_CONCAT(C.title) as title FROM list L
LEFT outer JOIN list_to_category LC ON L.list_id = LC.list_id
LEFT outer JOIN category C ON LC.category_id = C.id
group by L.name
Use GROUP_CONCAT for group by "list_id" for same name of list to fetch result :
SELECT L.name, GROUP_CONCAT(C.title) as title FROM list L
LEFT outer JOIN list_to_category LC ON L.list_id = LC.list_id
LEFT outer JOIN category C ON LC.category_id = C.id
group by L.list_id
It should be apparent from the code below that I'm no PHP coder. However, this should get the idea across. You can also use javascript/css to handle the transformation, which means things can be even more dynamic...
Oh, and I changed some table/column names - because I like it better that way...
<?php
require('path/to/connection/statements'); // $con
$query = "
SELECT l.list_id
, l.name
, l.description
, c.category_id
, c.title
, c.parent_id
FROM list l
JOIN list_category lc
ON lc.list_id = l.list_id
JOIN category c
ON c.category_id = lc.category_id
ORDER
BY l.list_id
, c.category_id;
";
$result = mysqli_query($con,$query);
$my_array = array();
while($row = mysqli_fetch_assoc($result)){
$my_array[] = $row;
}
$new_array = array();
foreach ($my_array as $row)
{
$new_array[$row['list_id']][$row['name']][$row['description']][] = $row['title'];
}
print_r($new_array);
?>
This will turn an array like this:
Array
(
[0] => Array
(
[list_id] => 1234
[name] => name1
[description] => sample description1
[category_id] => 1
[title] => Category 1
[parent_id] => 0
)
[1] => Array
(
[list_id] => 1234
[name] => name1
[description] => sample description1
[category_id] => 2
[title] => Category 2
[parent_id] => 0
)
[2] => Array
(
[list_id] => 1234
[name] => name1
[description] => sample description1
[category_id] => 3
[title] => Category 3
[parent_id] => 0
)
[3] => Array
(
[list_id] => 1235
[name] => name2
[description] => sample description2
[category_id] => 2
[title] => Category 2
[parent_id] => 0
)
[4] => Array
(
[list_id] => 1235
[name] => name2
[description] => sample description2
[category_id] => 3
[title] => Category 3
[parent_id] => 0
)
)
...into an array like this...
Array
(
[1234] => Array
(
[name1] => Array
(
[sample description1] => Array
(
[0] => Category 1
[1] => Category 2
[2] => Category 3
)
)
)
[1235] => Array
(
[name2] => Array
(
[sample description2] => Array
(
[0] => Category 2
[1] => Category 3
)
)
)
)
try this code
select l.name,c.title
from list_to_category lc join list l on lc.list_id=l.id
join category c on lc.catg_id=c.id

PHP - How to display data from array into a tree or table?

Currently, I have data retrieved from SELECT and converted into PHP assoc array. Thus, I got this array.
[0] => array
(
[Gattung] => 'Gattung_A'
[Untergattung] => null
[Sektion] => null
[Untersektion] => null
[Serie] => null
[Unterserie] => null
[Art] => 'Art_A'
[Unterart] => null
[Varietaet] => null
[SubVarietaet] => null
[Form] => 'Form_A'
[Unterform] => null
[SpezialForm] => null
[Hybride] => null
[Blendling] => null
[Sorte] => null
)
[1] => array
(
[Gattung] => 'Gattung_A'
[Untergattung] => null
[Sektion] => null
[Untersektion] => null
[Serie] => null
[Unterserie] => null
[Art] => 'Art_B'
[Unterart] => null
[Varietaet] => 'Variant_G'
[SubVarietaet] => null
[Form] => 'Form_B'
[Unterform] => null
[SpezialForm] => null
[Hybride] => null
[Blendling] => null
[Sorte] => null
)
[2] => array
(
[Gattung] => 'Gattung_B'
[Untergattung] => null
[Sektion] => null
[Untersektion] => null
[Serie] => null
[Unterserie] => null
[Art] => 'Art_C'
[Unterart] => null
[Varietaet] => 'Variant_A'
[SubVarietaet] => null
[Form] => null
[Unterform] => null
[SpezialForm] => null
[Hybride] => null
[Blendling] => null
[Sorte] => null
)
.........
Nearly ~300k records
So far, I have fixed my array into one dimensional array based on unique values by using array_unique. This is my result:
(
[0] => 'Gattung|Gattung_A'
[1] => 'Art|Art_A'
[3] => 'Form|Form_A'
[5] => 'Art|ArtB'
[7] => 'Varietaet|Variant_G'
[9] => 'Form|Form_G'
[11] => 'Gattung|Gattung_B'
[13] => 'Art|Art_C'
[15] => 'Varietaet|Variant_A'
}
However, my result is not well grouped. I need to display it on a page, so something like building a hierarchical system.
Question:
#Melsi I hope my second edit will purify my queston.
How to display the data into a tree
form (See Edit 2) or a table (See Edit
1)?
Thanks.
EDIT 1:
What I am doing is to create something like FULLTEXT search in several tables. This is the query to join all the tables:
(All FKs have index to each table's id )
SELECT
tGa.Gattung AS Gattung,
tUG.Untergattung AS Untergattung,
tSe.Sektion AS Sektion,
tUS.Untersektion AS Untersektion,
tSer.Serie AS Serie,
tUser.Unterserie AS Unterserie,
tA.Art AS Art,
tUa.Unterart AS Unterart,
tV.Varietaet AS Varietaet,
tSV.SubVarietaet AS SubVarietaet,
tF.Form AS Form,
tUF.Unterform AS Unterform,
tSF.SpezialForm AS SpezialForm,
tH.Hybride AS Hybride,
tBL.Blendling AS Blendling,
tSo.Sorte AS Sorte
FROM
botanischername AS tBot
LEFT JOIN ( gattung AS tGa ) ON ( tBot.ID_Ga = tGa.ID_Ga )
LEFT JOIN ( untergattung AS tUg ) ON ( tBot.ID_UG = tUg.ID_UG )
LEFT JOIN ( sektion AS tSe ) ON ( tSe.ID_Se = tBot.ID_Se )
LEFT JOIN ( untersektion AS tUS ) ON ( tUS.ID_US = tBot.ID_US )
LEFT JOIN ( serie AS tSer ) ON ( tSer.ID_Ser = tBot.ID_Ser )
LEFT JOIN ( unterserie AS tUSer ) ON ( tUser.ID_USer = tBot.ID_USer )
LEFT JOIN ( art AS tA ) ON ( tA.ID_A = tBot.ID_A )
LEFT JOIN ( unterart AS tUa ) ON ( tUa.ID_UA = tBot.ID_UA )
LEFT JOIN ( varietaet AS tV ) ON ( tV.ID_V = tBot.ID_V )
LEFT JOIN ( subvarietaet AS tSV ) ON ( tSV.ID_SV = tBot.ID_SV)
LEFT JOIN ( form AS tF ) ON ( tF.ID_F = tBot.ID_F )
LEFT JOIN ( unterform AS tUF ) ON ( tUF.ID_UF = tBot.ID_UF )
LEFT JOIN ( spezialform AS tSF ) ON ( tSF.ID_SF = tBot.ID_SF )
LEFT JOIN ( hybride AS tH ) ON ( tH.ID_H = tBot.ID_H )
LEFT JOIN ( blendling AS tBL ) ON ( tBL.ID_BL = tBot.ID_BL )
LEFT JOIN ( sorte AS tSo ) ON ( tSo.ID_So = tBot.ID_So )
LEFT JOIN ( status AS tST
CROSS JOIN pflanze AS tPfl) ON
( tST.ID_ST = tBot.ID_ST AND tPfl.ID = tBot.ID )
WHERE
tGa.Gattung LIKE #1_Word# OR
tUG.Untergattung LIKE #2_Word# OR
tSe.Sektion LIKE #3_Word# OR
tUS.Untersektion LIKE #4_Word# OR
tSer.Serie LIKE #5_Word# OR
tUser.Unterserie LIKE #6_Word# OR
tA.Art LIKE #7_Word# OR
tUa.Unterart LIKE #8_Word# OR
tV.Varietaet LIKE #9_Word# OR
tSV.SubVarietaet LIKE #10_Word# OR
tF.Form LIKE #11_Word# oR
tUF.Unterform LIKE #12_Word# OR
tSF.SpezialForm LIKE #13_Word# oR
tH.Hybride LIKE #14_Word# oR
tBL.Blendling LIKE #15_Word# OR
tSo.Sorte LIKE #16_Word#
I know that by using LIKE %xxx% OR is a heavy process. If you want to suggest me another way, it is fine.
My expected result is something like:
________________________________________________________________________________
| | | |______________________________Detail_____________|
| Num | Gattung | Art | Form | Varietaet | ...... | the other cols|
|------|-------------|-------|-----------|------------|--------|---------------|
| 1. | Gattung A | Art A | Form A | | | |
| | | <same | Form B | | | |
| | | data or Art A> | | | | |
| | | Art B | Form B | Variant G | | |
| 2. | Gattung B | Art C | | Variant A | | |
-------------------------------------------------------------------------------
Back 1 2 3 Next
EDIT 2 : Concise the question.
Or in tree form,
----- Art A ------ Form A
| |
| -- Form B
1. Gattung A ----|---- Art B ------ Form B ---- Variant G
2. Gattung B --------- Art C ------ Variant A
... And so on.
#exodream
Thank you for you comment.
This is my new answer to your question, it avoids empty lines, if you need to avoid empty coloumns or need something else let me know.
<?php
//make the labels
$labels=array('Gattung','Untergattung','Sektion','Untersektion','Serie',
'Unterserie','Art','Unterart','Varietaet','SubVarietaet','Form','Unterform',
'SpezialForm','Hybride','Blendling','Sorte' );
// Make a MySQL Connection
mysql_connect("localhost", "root", "") or die(mysql_error());
//select database
mysql_query("drop database if exists `test_db`;")or die(mysql_error());
mysql_query("create database `test_db`;")or die(mysql_error());
mysql_select_db("test_db") or die(mysql_error());
//create table
mysql_query(" drop table if exists `test_table`;")or die(mysql_error());
mysql_query("
CREATE TABLE `test_table` (
`Gattung` char(30) NULL ,
`Untergattung` char(30) NULL ,
`Sektion` char(30) NULL ,
`Untersektion` char(30) NULL ,
`Serie` char(30) NULL ,
`Unterserie` char(30) NULL ,
`Art` char(30) NULL ,
`Unterart` char(30) NULL ,
`Varietaet` char(30) NULL ,
`SubVarietaet` char(30) NULL ,
`Form` char(30) NULL ,
`Unterform` char(30) NULL ,
`SpezialForm` char(30) NULL ,
`Hybride` char(30) NULL ,
`Blendling` char(30) NULL ,
`Sorte` char(30) NULL
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB;") or die(mysql_error());
mysql_query("INSERT INTO `test_table` VALUES
('Gattung_A',null,null,null,null,null,'Art_A',null,null,null,'Form_A',null,null,null,null,null ) ")
or die(mysql_error());
mysql_query("INSERT INTO `test_table` VALUES
('Gattung_A',null,null,null,null,null,'Art_A',null,null,null,'Form_A',null,null,null ,null,null ) ")
or die(mysql_error());
mysql_query("INSERT INTO `test_table` VALUES
('Gattung_B',null,null,null,null,null,'Art_C',null,'Variant_A',null,null,null,null,null,null,null ) ")
or die(mysql_error());
mysql_query("INSERT INTO `test_table` VALUES
(null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null ) ")
or die(mysql_error());
mysql_query("INSERT INTO `test_table` VALUES
('Gattung_Q',null,null,null,null,null,'Art_C',null,'Variant_A',null,'Form_W',null,null,null,null,null ) ")
or die(mysql_error());
mysql_query("INSERT INTO `test_table` VALUES
('Gattung_Q',null,'test','test','test','test','Art_S','test','Variant_Y','test','Form_H','test','test','test','test','last' ) ")
or die(mysql_error());
//get result
$result = mysql_query("SELECT * FROM `test_table` ;")
or die(mysql_error());
normal_display();
non_empty_row_display();
non_empty_column_display();
function non_empty_row_display()
{
//get data
global $result;
$final_array=array();
global $result;
mysql_data_seek ($result , 0);
print '<b><br><h2>TABLE: 2 NON EMPTY VALUES OF EACH ROW</h2></b>';
print '<table border=7 bordercolor=orange >';
$index=0;
$color=array('#66CCFF','#00FF00');
//for every row of the table
while($row = mysql_fetch_row($result))
{
$current_row='';
//for every coloumn
foreach ($row as $value)
//if value is not null
if($value!=null)//then keep it
$current_row .= $value.' | ';
if($current_row!='')
echo '<tr bgcolor=',$color[$index%2],'><th>ROW ',$index++,'</th><td>',$current_row,'</td></tr>',
'<tr><td colspan=2 height=5 bgcolor=pink></td></tr>';
}//while
echo '</table>';
}//function
function normal_display()
{
print '<b><h2>TABLE:1 Normal display</h2></b>';
print '<table border=1><tr>';
global $labels;
foreach($labels as $value)
echo '<th>',$value,'</th>';
print '</tr>';
global $result;
while($row = mysql_fetch_row($result))
{
print '<tr>';
foreach($row as $value)
echo '<td>',$value,' </td>';
print '</tr>';
}//while
print '</table>';
}//function
function non_empty_column_display()
{
//get data
global $result;
mysql_data_seek ($result , 0);
//for every row of the table
$final_column=array();
while($row = mysql_fetch_row($result))
//for every coloumn
foreach ($row as $key => $value)
//if value is not null
if($value!=null)
//if $final_column[$key] exists append value to it, otherwise assign value
$final_column[$key]=(isset($final_column[$key]))?$final_column[$key].=$value.'<br>':$value.' <br> ';
echo '<br><br><h2>Array:1 </h2>The coloumn with index 6 is placed before the one with index 2 in this array
because its first non empty value is fetched earlier. Check for your self:<br>';
echo '<pre>',strip_tags(print_r($final_column,true)),'</pre>';
//for each mysql table coloumn name
global $labels;
foreach($labels as $key => $value)
//if it exists in the result
if(array_key_exists($key,$final_column))
//keep it
$label_header=(isset($label_header))?$label_header.='<th>'.$value.'</th>':'<th>'.$value.'</th>';
ksort($final_column);
echo '<br><br><h2>Array:2 </h2>We can order this. Check for your self:<br>';
echo '<pre>',strip_tags(print_r($final_column,true)),'</pre>';
echo '<br><b><h2>TABLE:3 </h2>THIS IS A TABLE WITH NON EMPTY COLOUMNS<b>';
echo '<table border=1>',$label_header,'<tr>';
foreach($final_column as $value)
echo '<td valign=top>',$value,'</td>';
echo '</tr></table>';
}//function
?>
I have already fixed lines 147 and 161 (for previous example), it was a warning, we have to check if a variable exists before concatenation, in your example it would be:
147:
$final_column[$key]=(isset($final_column[$key]))?$final_column[$key].=$value.'<br>':$value.' <br> ';
161:
$label_header=(isset($label_header))?$label_header.='<th>'.$value.'</th>':'<th>'.$value.'</th>';
1) if you it is possible to do the sorting / grouping / aggregation in SQL then do it in SQL - not in PHP. SQL and rDBMS are designed and optimized for this.
2) PHP does not have multidimesnional arrays - they are hierarchical.
3) if you don't want nulls in your array don't put them there
4) If you have a primary key for the result set in your data use that for your array key
while ($r=mysql_fetch_assoc($result)) {
foreach($r as $key=>$val) {
if ($val || $val===0 || $val===false) {
$array[$r['Art']][$key]=$val;
}
}
}

Categories