I have the following scenario.
I have 2 tables as follow
Table 1
ID, Name, Desc, Seo
Table 2
ID, Table1_ID, Relation_Table1_ID
in Table 1 I have all my data that I need as:
-----------------------------------
|ID | Name |Desc |Seo |
-----------------------------------
| 1 | Smith |Father |f |
| 2 | Jonh |Son |j |
| 3 | Margat |Mother |m |
| 4 | Bis3 |son |b1 |
| 5 | Bis2 |son |b2 |
| 6 | Bis1 |son |b3 |
| 7 | Lanos |Brother |l |
-----------------------------------
And then we have our table 2 as follow
-------------------------------------
|ID | Table1_ID |Relation_Table1_id|
--------------------------------------
| 1 | 1 | 4 |
| 2 | 1 | 5 |
| 3 | 3 | 6 |
| 4 | 3 | 2 |
| 5 | 7 | 0 |
--------------------------------------
So far I have my first table dump with jSON() as follow:
<?php
include ('config.php');
$dump1 = mysql_query("SELECT * FROM Table1 ") or die(mysql_error());
$getList = array();
while ($row = mysql_fetch_assoc($dump1)) {
$getList[] = $row;
}
print json_encode($getList); exit;
?>
That code will give me the following:
[
{
"ID":"1",
"Name":"Smith",
"Desc":"Father",
"Seo":"f"
},
{
"ID":"2",
"Name":"Jonh",
"Desc":"Son",
"Seo":"j"
},
{
"ID":"3",
"Name":"Margat",
"Desc":"Mother",
"Seo":"m"
}... ... ...
]
What I can't figure is how do I get the following
[
{
"ID":"1",
"Name":"Smith",
"Desc":"Father",
"Seo":"f",
"Relations":[
{
"ID":"4",
"Name":"Bis3",
"Desc":"Son",
"Seo":"b1"
}
]
},
{
"ID":"3",
"Name":"Margat",
"Desc":"Father",
"Seo":"f",
"Relations":[
{
"ID":"6",
"Name":"Bis2",
"Desc":"Son",
"Seo":"b2"
},
{
"ID":"2",
"Name":"Jonh",
"Desc":"Son",
"Seo":"j"
}
]
}... ... ...
]
In plain text it would be something like
ID 1 Smith
| |_ID 4 Bis3
|
|_ ID 3 Margat
|_ID 5 Bis2
|_ID 2 Jonh
I'm learning how to use json and I just got the first part as you can see, but my lack of knowledge of SQL and php wont let me get the what I really want, so please can any one help me achieve this scenario please.
Thank you.
you can loop through $getlist
then query
for($i = 0; $i <= count($getlist); $i++){
"SELECT * FROM Table2 WHERE Table1_ID = $getlist[$i]['ID']"
// get the result however way
$getlist[$i]['something'] = $result;
}
then take the result of that, inside the loop, and assign it to whichever key of getlist you want
for example
hopefully thats specific enough. let me know if you have problems with that.
You need to join across the two tables. First, join the second table with the first table. This can be done with the following code:
select * from table_2 as t2 join table_1 as t1 on t1.id = t2.rel_id;
which results in:
+------+-----------+--------+------+------+------+------+
| ID | table1_id | rel_id | ID | name | desc | seo |
+------+-----------+--------+------+------+------+------+
| 4 | 3 | 2 | 2 | John | Son | j |
| 1 | 1 | 4 | 4 | Bis3 | son | b1 |
| 2 | 1 | 5 | 5 | Bis2 | son | b2 |
| 3 | 3 | 6 | 6 | Bis1 | son | b3 |
+------+-----------+--------+------+------+------+------+
now we want to join the columns if the table1_id is the same. This can be done with the GROUP_CONCAT command:
select table1_id,group_concat(t1.name) as name_rel,
group_concat(t1.desc) as desc_rel, group_concat(seo) as seo_rel,
group_concat(rel_id) as id_rel from table_2 as t2 join table_1 as t1 on
t2.rel_id = t1.id group by t2.table1_id
which results in:
+-----------+-----------+----------+---------+--------+
| table1_id | name_rel | desc_rel | seo_rel | id_rel |
+-----------+-----------+----------+---------+--------+
| 1 | Bis2,Bis3 | son,son | b2,b1 | 5,4 |
| 3 | John,Bis1 | Son,son | j,b3 | 2,6 |
+-----------+-----------+----------+---------+--------+
The as command can be used to rename columns in the output. Try running the query without it and you should see column names like group_concat(t1.name) instead of name_rel.
Now we want to join this selection with table_1 where the table1_id is the same as the id in table1. This can be done with the following query:
select * from (
select table1_id,group_concat(t1.name) as name_rel,
group_concat(t1.desc) as desc_rel, group_concat(seo) as seo_rel,
group_concat(rel_id) as id_rel from table_2 as t2 join table_1 as t1 on
t2.rel_id = t1.id group by t2.table1_id
) as joined_table
join table_1 as t3 on t3.id = joined_table.table1_id;
which results in:
+-----------+-----------+----------+---------+--------+------+--------+--------+------+
| table1_id | name_rel | desc_rel | seo_rel | id_rel | ID | name | desc | seo |
+-----------+-----------+----------+---------+--------+------+--------+--------+------+
| 1 | Bis2,Bis3 | son,son | b2,b1 | 5,4 | 1 | Smith | Father | f |
| 3 | John,Bis1 | Son,son | j,b3 | 2,6 | 3 | Margat | Mother | m |
+-----------+-----------+----------+---------+--------+------+--------+--------+------+
As you can see, you know have all the data. All that is left is to turn the *_rel columns into separate objects, which can be done in php. Go ahead and give that a shot. I've gotta go for now, but I'll edit this post later if you're still having trouble.
Alright, I'm back. My php is rusty, but something along these lines should work:
while ($row = mysql_fetch_assoc($dump1)) {
$name_rel = explode("," , $row["name_rel"]);
$desc_rel = explode("," , $row["desc_rel"]);
$seo_rel = explode("," , $row["seo_rel"]);
$id_rel = explode("," , $row["id_rel"]);
$relations = array();
for($i = 0; $i < count($id_rel); ++$i){
$temp = array("ID" => $id_rel[$i],
"Name" => $name_rel[$i],
"Desc" => $desc_rel[$i],
"Seo" => $seo_rel[$i],);
$relations[] = $temp ;
}
unset($row["id_rel"]);
unset($row["name_rel"]);
unset($row["desc_rel"]);
unset($row["seo_rel"]);
$row["Relations"] = $relations ;
$getList[] = $row;
}
print json_encode($getList); exit;
This will create each of the Relations objects and add them to the row. The unset commands should remove the keys we no longer care about (id_rel, name_rel, desc_rel, and seo_rel). We no longer care about them because their data should have been moved to the Relations object.
Related
I have 1 master_table and 2 sub_tables. I want the join the 3 columns together (but the problem is the 2 sub_tables do not have any column that share the same value) and then SELECT * based on 2 different columns from the 2 sub_tables.
I've searched and tried many ways of coding, but couldn't find a solution.
SELECT *
FROM (master INNER JOIN sub_1 ON master.id=sub_1.id WHERE sub_1.column_1 = 'Y')
AND (master INNER JOIN sub_2 ON master.id=sub_2.id WHERE sub_2.column_2 = 'Y')
ORDER BY master.id
++++++++++++++++++++++++++++++++++++++++++++++++++
* Finally, solved. See the solution at the bottom of this post. *
++++++++++++++++++++++++++++++++++++++++++++++++++
===========
Edit: explain more about my data, problem and MySQL code
I have 3 tables stored in MySQL as follow
Master_table: regist
------------------------------------------
| reg_no | firstname | lastname | submit |
------------------------------------------
| 1 | first_A | last_A | N |
| 2 | first_B | last_B | A |
| 3 | first_C | last_C | P |
| 4 | first_D | last_D | P |
| 5 | first_E | last_E | A |
| 6 | first_F | last_F | N |
| 7 | first_G | last_G | N |
| 8 | first_H | last_H | A |
------------------------------------------
Sub_1: sub_A Sub_2: sub_P
------------------------------ ------------------------------
| reg_no | A_title | reply_A | | reg_no | P_title | reply_P |
------------------------------ ------------------------------
| 2 | 222 | Y | | 3 | 333 | N |
| 5 | 555 | N | | 4 | 444 | Y |
| 8 | 888 | Y | ------------------------------
------------------------------
I want to create a query that gives result like this
----------------------------------------------------------------------------------
| reg_no | firstname | lastname | submit | A_title | reply_A | P_title | reply_P |
----------------------------------------------------------------------------------
| 2 | first_B | last_B | A | 222 | Y | | |
| 8 | first_H | last_H | A | 888 | Y | | |
| 4 | first_D | last_D | P | | | 444 | Y |
----------------------------------------------------------------------------------
or
-----------------------------------------------------------
| reg_no | firstname | lastname | submit | title | reply |
-----------------------------------------------------------
| 2 | first_B | last_B | A | 222 | Y |
| 8 | first_H | last_H | A | 888 | Y |
| 4 | first_D | last_D | P | 444 | Y |
-----------------------------------------------------------
$sql = "SELECT *
FROM (regist INNER JOIN sub_A ON regist.reg_no = sub_A.reg_no WHERE sub_A.reply_A = 'Y')
AND (regist INNER JOIN sub_P ON regist.reg_no = sub_P.reg_no WHERE sub_P.reply_P = 'Y')
ORDER BY regist.reg_no";
Expected outcome:
ECHO personal data of all registrants who got reply as 'Y'
if($row['submit']=="A") $title = $row['A_title'];
elseif($row['submit']=="P") $title = $row['P_title'];
$result = mysql_query($sql) or die(mysql_error());
while($row = mysql_fetch_array($result))
{
echo $row['reg_no']." / ".$row['firstname']." ".$row['lastname']." / ".$title."<br>";
}
Problem: my SELECT code resulted in error. The code from #GMB and #Rogue didn't error, but echo give nothing.
If it is not possible to code a query as I want, I will just modify the column names (sub_1.reply_A and sub_2.reply_P) to be the same and change the input code in other webpages. However, it would be best if there is a way because I don't know whether the 'reply' columns were used somewhere else.
========================
Solution: a little modification from #Rogue code
SELECT *
FROM master
LEFT OUTER JOIN sub_1
ON master.id=sub_1.id
LEFT OUTER JOIN sub_2
ON master.id=sub_2.id
WHERE sub_1.column_1 = 'Y'
OR sub_2.column_2 = 'Y'
ORDER BY master.id
Do you just want simple JOINs between these 3 tables ?
SELECT m.*, s1.*, s2.*
FROM master m
INNER JOIN sub_1 s1 ON m.id=s1.id AND s1.column_1 = 'Y'
INNER JOIN sub_2 s2 ON m.id=s2.id AND s2.column_2 = 'Y'
ORDER BY m.id;
If you have master records that may not exist in both sub tables, you can switch to LEFT JOIN to avoid filtering them out.
Guidelines :
typical syntax is SELECT ... FROM table1 INNER JOIN table2 ON ... INNER JOIN table3 ON...
better put all conditions related to a JOINed table in the ON clause of the join rather than in the WHERE clause
avoid SELECT * : be specific about the columns you want to select
use table aliases to make the query easier to read
You're a little off syntactically:
SELECT *
FROM master
LEFT OUTER JOIN sub_1
ON master.id=sub_1.id
LEFT OUTER JOIN sub_2
ON master.id=sub_2.id
WHERE sub_1.column_1 = 'Y'
AND sub_2.column_2 = 'Y'
ORDER BY master.id
Personally I would recommend not using SELECT * and only grabbing the data you will need. As for determining what join to use, I like to link to CodingHorror's blog post in these times.
Edit: swapped INNER to LEFT OUTER, per OP's update
Hello I have two tables to send consecutive queries.
For example, table A yields 1,2,3 ..
Then, look for data in table B of query 1,2,3 ..
tableA
_____________________
| uid | rate |
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
| 2 | 4 |
tableB
_________________________
| rate | text |
| 1 | ONE |
| 2 | TWO |
| 3 | THREE |
| 4 | FOUR |
===
<?php
$sql = $con->query("SELECT * FROM tableA WHERE uid=1");
$user = $sql->fetch_array();
$ratings = $user['rate']; //1,2,3
$sql2 = $con->query("SELECT * FROM tableB WHERE rate IN('".$ratings."')");
$text = $sql2->fetch_array();
$results = $text['text']; //ONE, TWO, THREE
?>
How best to do that?
You can use this query:
Select tableA.*,tableB.*
from tableA
join tableB on tableA.rate=tableB.rate
where tableA.uid=1
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;
}
I have 3 table now:
First is : member_username
+-------------+------------------+
| uid | username |
+-------------+------------------+
| 1 | theone |
| 2 | ohno |
| 3 | prayforpr |
+-------------+------------------+
Second is : member_data
+-------------+-------------------+-----------------+
| uid | talk | etc |
+-------------+-------------------+-----------------+
| 1 | talk1 | |
| 2 | talkeee | |
| 3 | iojdfnl | |
+---------------------------------------------------+
Third is : member_level
+-------------+-------------------+-----------------+
| uid | level | fid |
+-------------+-------------------+-----------------+
| 1 | 2 | 1 |
| 1 | 10 | 2 |
| 2 | 1 | 1 |
| 2 | 99 | 2 |
| 1 | 40 | 3 |
| 3 | 50 | 1 |
| 1 | 44 | 4 |
+---------------------------------------------------+
I would like to query data and display the only one uid when member_level is higher in when SUM member_level.level Where fid in 1,2,3.
my query now is like below, but this query is sum all the level including fid 4 also, how to specify only sum in fid 1,2,3? and how do I assign the SUM of member_level.level Where fid in 1,2,3 to $levelKingTotalLevel?
$levelKing = DB::query("SELECT t1.uid,t1.username,t2.talk FROM ".DB::table('member_level')." t3 JOIN ".DB::table('member_username')." t1 ON(t3.uid = t1.uid) JOIN ".DB::table('member_data')." t2 ON (t1.uid = t2.uid) GROUP BY t3.uid ORDER BY SUM(t3.level) DESC LIMIT 1");
while($rowlevelKing = DB::fetch($levelKing)) {
$levelKingTotalLevel = $rowlevelKing['???'];
$levelKingN = $rowlevelKing['username'];
$levelKingUID = $rowlevelKing['uid'];
$levelKingT = $rowlevelKing['talk'];
};
echo "The ".$levelKingN." total level is ".$levelKingTotalLevel." and he talk about ".$levelKingT;
Thank you.
To filter records having fid values as 1, 2 or 3, use IN statement in WHERE clause. Alias totalLevel in select statement will give you total level for a user.
SELECT t1.uid, t1.username, t2.talk, SUM(t3.level) AS totalLevel
FROM member_level t3
JOIN member_username t1
ON (t3.uid = t1.uid)
JOIN member_data t2
ON (t1.uid = t2.uid)
WHERE t3.fid IN (1,2,3)
GROUP BY t3.uid
ORDER BY totalLevel DESC
LIMIT 1
I have tables illustrated below
//reference type table
+---+-----------+---------+
|ID |Article_ID |Ref_Types|
+---+-----------+---------+
| 1 | 1 | article |
| 2 | 1 | book |
| 3 | 1 | article |
| 4 | 1 | article |
| 5 | 2 | book |
+---+-----------+---------+
//book references table
+---+-----------+--------+
|ID |Article_ID |Title |
+---+-----------+--------+
| 1 | 1 | book1 |
| 2 | 1 | book2 |
| 3 | 2 | book3 |
| 4 | 2 | book4 |
| 5 | 2 | book5 |
+---+-----------+--------+
//article references table
+---+-----------+-----------+
|ID |Article_ID |Title |
+---+-----------+-----------+
| 1 | 1 | article1 |
| 2 | 1 | article2 |
| 3 | 2 | article3 |
| 4 | 2 | article4 |
| 5 | 2 | article5 |
+---+-----------+-----------+
I have to look into first table and check the reference, of which type it is;
for each reference type, I have get reference table from related table
I have to output in order, as shown in table one.
1:
$data=array();
$sql=mysql_query("SELECT * FROM reftypes
WHERE Article_ID=1 ORDER BY ID ASC");
while($row = mysql_fetch_array($sql)){
$data[]=$row[2]; // i store in an array so that i can use later..
}
2:
foreach ($data as $ref) {
$counter=1;
switch ($ref) {
case "article":
$sqlarticle= mysql_query("SELECT Title
FROM book WHERE Article_ID=1 ORDER BY ID ASC");
echo mysql_result($sqlarticle, $counter); //i want to get only one out of book table
$counter++;
break;
...
...
But $sqlarticle does not seem to work.
I want to display as:
+-----------+----------+
|Article_ID |Reference |
+-----------+----------+
| 1 | article1 |
| 1 | book1 |
| 1 | article2 |
| 1 | article3 |
+-----------+----------+
I know it is a long question and for experts or experienced people it is very trivial, but that is where I'm stuck.
SELECT
*
FROM
reftypes R
WHERE
Article_ID=your_id
LEFT JOIN books B ON (B.Article_ID = R.Article_ID AND R.Ref_Types = 'book')
LEFT JOIN articles A ON (A.Article_ID = R.Article_ID AND R.Ref_Types = 'article')
ORDER BY
R.id ASC;
Even if the database is wrongly modeled, I think.
What about the followin model instead?
""although especially question owners should respect any kind of effort and input, -i am thankful- i can not understand why some people try to think of question's holder as well-informed or experienced as themselves, or worse comment from higher level. ""
anyway, my question was about to get values one by one, here is how i did it;
$data=array();
$sql=mysql_query("SELECT * FROM reftypes
WHERE Article_ID=1 ORDER BY ID ASC");
while($row = mysql_fetch_array($sql)){
$data[]=$row[2]; // i store in an array so that i can use later..
}
$articlecount=0;
$bookcount=0;
foreach ($data as $value) {
switch ($value) {
case "article":
$sqlarticle=mysql_query("SELECT RefArticleTitle
FROM ref_article
WHERE $article_ID=Article_ID
ORDER BY ID ASC");
$articles= mysql_result($sqlarticle, $articlecount);
echo $articles;
echo "\n";
$articlecount++;
break;
case "book":
$sqlbook=mysql_query("SELECT RefBookName
FROM ref_book
WHERE $article_ID=Article_ID
ORDER BY ID ASC");
$books= mysql_result($sqlbook, $bookcount);
echo $books;
echo "\n";
$bookcount++;
break;
...
...
as a result, i got what i required..
+-----------+----------+
|Article_ID |Reference |
+-----------+----------+
| 1 | article1 |
| 1 | book1 |
| 1 | article2 |
| 1 | article3 |
+-----------+----------+
thanks to whoever interested in the topic..
$result=mysqli_query("select ref_types from reference type");
while($row=mysqli_fetch_array($result))
{
$table=$row[0];
$result1=mysqli_query("select * from $table");
while($row1=mysqli_fetch_array($result1))
{
var_dump($row1);
}
}