PHP MYSQL INNER JOIN to JSON - php

I had a two table,
First one : table product table product
| id | name | code |
| 1 | blouse | AB1 |
| 2 | jeans | BA2 |
| 3 | dress | C61 |
and the second table color table color
| id_product | colors | amount |
| 1 | blue | 50 |
| 1 | red | 40 |
| 1 | yellow| 10 |
| 2 | white | 15 |
| 2 | blue | 60 |
| 3 | purple| 110 |
Query : my query php
.../blabla
SELECT product.id, product.name, product.code,color.id_product, color.colors, color.amount
FROM product
INNER JOIN color
ON product.id = color.id_product limit 1
while($query)) {
$var[] = $query;
}
echo '{"status":'. json_encode($var).'}';
OUTPUT :
{
"status":{
"1":{
"id":"1",
"code":"blouse",
"id_product":"1",
"colors":"blue",
"amount":"50",
}
}
}
what i want JSON like this :
{
"status":{
"1":{
"id":"1",
"code":"blouse",
"id_product":"1",
"colors":"blue",
"amount":"50",
"id_product":"1",
"colors":"red",
"amount":"40",
"id_product":"1",
"colors":"yellow",
"amount":"10",
}
}
}
Need color into one array json, is that possible?

So you should probably use group_concat to get them into a list and then use PHP to explode the list before encoding to json.
SQL Fiddle Here
http://sqlfiddle.com/#!9/ba3b8/3
SELECT product.id, product.name, product.code,
color.id_product, color.colors, color.amount,
group_concat(color.colors) as clist,
group_concat(color.amount) as alist
from product, color
where product.id = color.id_product
group by color.id_product
Then in your PHP you would need to loop through the results, using explode to convert the list to an array and inserting the data into the results as needed PRIOR to using json_encode();

You should use this query:
SELECT product.id, product.name, product.code
color.id_product, color.colors, color.amount
from product
INNER JOIN color
ON product.id = color.id_product
where product.id=1
LIMITwill give you exactly one record.

Related

How to select only one record of each category?

Products :
--------------------------------------------
| ID | Group | Name | Sold |
--------------------------------------------
| 1 | A | Dell | 0 |
--------------------------------------------
| 2 | A | Dell | 0 |
--------------------------------------------
| 3 | B | Dell | 1 |
--------------------------------------------
| 4 | B | Dell | 1 |
--------------------------------------------
| 5 | C | Dell | 0 |
--------------------------------------------
| 6 | C | Dell | 1 |
--------------------------------------------
Hi everyone, i have a table (products) stored in MySql with many records, for now i'm using this query SELECT * FROM products WHERE sold = 0, in results i get :
--------------------------------------------
| ID | Group | Name | Sold |
--------------------------------------------
| 1 | A | Dell | 0 |
--------------------------------------------
| 2 | A | Dell | 0 |
--------------------------------------------
| 5 | C | Dell | 0 |
--------------------------------------------
i want to get only one record from each group, so the results will be like :
--------------------------------------------
| ID | Group | Name | Sold |
--------------------------------------------
| 1 | A | Dell | 0 |
--------------------------------------------
| 5 | C | Dell | 0 |
--------------------------------------------
You could easily do this by using a distinct clause and removing the id column. If you want to keep the id column you need to specify how one would chose which id to keep.
select distinct
`group`
, name
, sold
from
products
where
sold = 0;
To keep the row with the smallest id (as your example shows) something along the lines of the example below would work.
select
id
, `group`
, name
, sold
from
products
where
sold = 0
and id = (
select
min(p.id)
from
products p
where
p.`group` = products.`group`
and p.sold = 0
);
First, change your field named Group to something like Group_Name. GROUP is a reserved keyword, and if it is not causing you problems now it probably will later.
Second, you should ask yourself what you are really after. The following query should generate your desired result. It adds an additional condition where the IDs that are returned are the lowest numbered ID in each group.
SELECT * FROM products
WHERE sold = 0
AND ID IN (SELECT MIN(ID) FROM products WHERE sold = 0 GROUP BY Group_Name)
Why do you want that, though? That is not a normal desired end state. You should ask yourself why you care about the ID. It looks like your goal is to figure out which products have not sold anything. In that case, I would recommend this instead:
SELECT DISTINCT Group_Name, Name
FROM products
WHERE sold = 0
ORDER BY Group_Name, Name
I found the solution by using the statement GROUP BY,
SELECT * FROM products WHERE sold = 0 GROUP BY group
in the results now, i get only one record for each group and the minimal id without adding any other statement, and in my real table i am using product_group instead of group because it's a reserved word.
Try this:
SELECT `ID`, `Group`, `Name`, `Sold` FROM products WHERE sold = 0 GROUP BY `Group`;

How to select values from two different tables in SQL

I have two tables in my SQL Server database. The first is catgeories and second is products. There is a column categories_id in both tables.
HERE IS MY TABLE FOR CATEGORIES :
+----+----------+----------+
| id | category | parent |
+----+----------+----------+
| 1 | BOY | 0 |
| 2 | GIRL | 0 |
| 3 | SHIRT | 1 |
| 4 | SKIRT | 2 |
| 5 | JACKET | 1 |
+----+----------+----------+
TABLE : PRODUCTS
+-------+--------------+----------------------+
| id | title |PRICE | Categories |
+-------+--------------+------+---------------+
| 1 | RED SHIRT | 300 | 3 |
| 2 | blue SKIRT | 500 | 4 |
| 3 | jeans jacket | 500 | 3 |
+-------+--------------+------+-----+---------+
Now I want to select the values from Products table for a particular category like BOY.
Try This:
SELECT pr.id,pr.title,pr.price from products AS pr
INNER JOIN CATEGORIES AS cat ON cat.id=pr.Categories
WHERE cat.category='Boy';
SELECT products.* FROM products INNER JOIN categories ON products.categories = categories.id WHERE categories.category LIKE '%BOY%';
Use this query..
Either
SELECT * FROM tproducts WHERE categories = 1
or
SELECT * FROM tproducts
JOIN tcategories ON tcategories.id = tproducts.categories WHERE tcategories.category = 'BOY'
I don't know your table names so I just used tproducts and tcategories
There is no boy(1) ID in Categories(field) in PRODUCTS(table)
SELECT * FROM CATEGORIES
INNER JOIN PRODUCTS
ON CATEGORIES.id=PRODUCTS.Categories
WHERE CATEGORIES.category ='BOY'
FOR this use join query Example:
select *(or you can get any column as you write name) from table1 join table2 on table1.id=table2.id where table1.category='BOY';

How to map matched records returned from a join instead of separate rows

Scenario :
I have two tables, structured as following.
Table 1 : images
+--------+------------+
| img_id | img_name |
+--------+------------+
| 1 | image1.jpg |
| 2 | image2.jpg |
| 3 | image3.jpg |
+--------+------------+
Table 2 : image_tags
+---------+--------+----------+--------+--------+
| cord_id | img_id | tag_text | xcord | ycord |
+---------+--------+----------+--------+--------+
| 1 | 1 | Tag1 | 28.1 | 30.4 |
| 2 | 1 | Test Tag | 23.4 | 4.5 |
+---------+--------+----------+--------+--------+
Now i want the images along with their tags which is quite simple using the left join
SELECT img_id, img_name,tag_text, xcord,ycord FROM images t1 LEFT JOIN image_tags t2 ON t1.id=t2.id
This query results in the following data set
+--------+------------+----------+--------+--------+
| img_id | img_name | tag_text | xcord | ycord |
+--------+------------+----------+--------+--------+
| 1 | image1.jpg | Tag1 | 28.1 | 30.4 |
| 1 | image1.jpg | Test Tag | 23.4 | 4.5 |
| 2 | image2.jpg | NULL | NULL | NULL |
| 3 | image3.jpg | NULL | NULL | NULL |
+--------+------------+----------+--------+--------+
Problem :
Now using PHP (or MYSQL if possible), i want the results from the image_tags table to be concatenated with each row in form of an array.
So that when i loop through the records in Angular, i have images along with their tags in form of an array instead of two separate rows as you can see the first two rows in the result set.
Desired result example,
{
cord_id : 1,
img_id : 1,
tags : [{
tag_text : "Tag1",
xcord : 28.1,
ycord : 30.4,
},{
tag_text : "Test Tag",
xcord : 23.4,
ycord : 4.5,
}
]
}
I have studied about map() function in PHP but unable to achieve this.
Note: I am using Codeigniter, so if that has some relevant support to achieve this, that would also work for me.
Any help would be highly appreciated. Thanks
It is possible to do it with just one query.
Since you have a unique ID you can use it as an index for your array.
$images = array();
foreach($queryResults as $result){
if(!isset($images[$result['img_id']])){
$images[$result['img_id']] = array();
$images[$result['img_id']]['cord_id'] = $result['cord_id'];
$images[$result['img_id']]['img_id'] = $result['img_id'];
$images[$result['img_id']]['tags'] = array();
}
$tag = array(
'tag_text'=>$result['tag_text'],
'xcord'=> $result['xcord'],
'ycord'=> $result['ycord']
);
$images[$result['img_id']]['tags'][] = $tag;
}

Compare column from two rows and if different change values of another column

I have a table with an auto increment key id, item_no can be either one or two rows in a row (so they always have consecutive ids) that share the same ref but have different right/left (but technically item_no can be repeated multiple times throughout the table but that's not an issue), and description will sometimes be the same on the consecutive rows but sometimes different:
id | item_no | description | right\left | ref
1 | 1 | a1 | right | aaa
2 | 1 | a1 | left | aaa
3 | 2 | b1 | right | bbb
4 | 3 | c1 | right | ccc
5 | 3 | c2 | left | ccc
6 | 4 | d1 | right | ddd
7 | 4 | d1 | left | ddd
My issue is that I need item_no to append a -r or -l on to its value if the description of its 'matching' row is different.
So the result I am looking for is:
id | item_no | description | right\left | ref
1 | 1 | a1 | right | aaa
2 | 1 | a1 | left | aaa
3 | 2 | b1 | right | bbb
4 | 3-r | c1 | right | ccc
5 | 3-l | c2 | left | ccc
6 | 4 | d1 | right | ddd
7 | 4 | d1 | left | ddd
I am exporting the table to a csv but am not using much php, just a mysql statement and then looping out the results, is this possible within the mysql statement or will I have to rely on a php loop?
I would use this:
update
items inner join
(select item_no from items
group by item_no
having count(distinct description)>1) dup
on items.item_no=dup.item_no
set
items.item_no=concat(items.item_no, '-', substr(rightleft, 1,1))
If rows are always consecutive, you could also use this:
update
items i1 inner join items i2
on (i1.id=i2.id+1 or i1.id=i2.id-1)
and (i1.item_no=i2.item_no)
and (i1.description<>i2.description)
set i1.item_no=concat(i1.item_no, '-', substr(i1.rightleft, 1,1))
EDIT: if rows are always consecutive, and you just need a select and not an update, you could use this:
select
i1.id,
case when i1.description=i2.description or i2.id is null then i1.item_no else
concat(i1.item_no, '-', substr(i1.rightleft, 1,1)) end,
i1.description, i1.rightleft, i1.ref
from
items i1 left join items i2
on (i1.id=i2.id+1 or i1.id=i2.id-1) and (i1.item_no=i2.item_no)
order by i1.id
Try this:
SELECT
id,
CASE RightLeft
WHEN 'right' THEN CONCAT(item_no, '-r' )
WHEN 'left' THEN CONCAT(item_no, '-l' )
END AS item_no,
DESCRIPTION,
Rightleft,
ref
FROM Items
WHERE item_no IN
(
SELECT i1.item_no
FROM items i1
GROUP BY i1.item_no
HAVING(COUNT(DISTINCT description)) > 1);
SQL Fiddle Demo
This will give you:
| ID | ITEM_NO | DESCRIPTION | RIGHTLEFT | REF |
------------------------------------------------
| 4 | 3-r | c1 | right | ccc |
| 5 | 3-l | c2 | left | ccc |
I would rely on a PHP loop if you're using mysql, if you were using Oracle or SQL server then you could program a stored procedure.
You script should look something like this:
$dbh = new PDO('mysql:host='.DATABASE_HOST.';dbname='.DATABASE_NAME, DATABASE_USER, DATABASE_PASSWORD);
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$data = $dbh->query("SELECT * FROM ExampleTable");
$dbh->beginTransaction();
foreach($data as $row)
{
$append = $row["right\left"] == "left" ? $row["item_no"]."-l" : $row["item_no"]."-r";
$stmnt = $dbh->prepare("UPDATE ExampleTable SET item_no = :item WHERE id = :id");
$stmnt->execute(array(":item" => $append,":id" => $row["id"]));
}
// Do some exception handling if something goes wrong you can allways do a rollback
// With PDO $dbh->rollBack();
$dbh->commit();
$dbh = null;
Something like this
UPDATE [dbo].[maTable] SET [item_no] = [item_no]+'r' WHERE not distinct [description] from [dbo].[maTable]
Should add an 'r' in the registration line where [description] is not identical (coded for SQL Server)

Need help with a MySQL statement

I have a table of Products that looks like so:
| id | Description | Price |
| 1 | dinglehopper | 2.99 |
| 2 | flux capacitor | 48.99 |
| 3 | thing1 | 48.99 |
And so on...
Then I have an OrderLineItem table which, as you can guess, links each item in an order to the product:
| id | productID | OrderID |
| 43 | 1 | 12 |
| 44 | 2 | 12 |
| 52 | 3 | 15 |
So, as you can see, order #12 contains a dinglehopper and flux capacitor. How can I get this information in a single query? I just want ALL the products associated with a given OrderID in the OrderLineItem table.
May be by
select p.description,p.id,o.irderId
from
`orderLineItem` o, `product` p
where
p.id = o.productId;
or
select p.description,p.id,o.irderId
from `orderLineItem` o
join `product` p
on p.id = o.productId;
LEFT JOIN :)
http://www.w3schools.com/sql/sql_join_left.asp
#Pete About "single" query part, you should make VIEW from this join, if really going to use a lot.

Categories