Inserting value in one column from another table mysql - php

school
+-----+-----------+----------+
| id | the_photo | column3 |
+-----+-----------+----------+
| 11 | NULL | abc |
| 22 | NULL | asf |
| 33 | NULL | asag |
+-----+-----------+----------+
school_images
+-----+-----------+-------+
| id | school_id | photo |
+-----+-----------+-------+
| 1 | 11 | 1 |
| 2 | 22 | 0 |
| 3 | 33 | 1 |
+-----+-----------+-------+
...
Need to insert values into the_photo column of school only if photo value = 1 for school_images like this:
School
+-----+-----------+
| id | the_photo |
+-----+-----------+
| 11 | 1 |
| 22 | NULL |
| 33 | 3 |
+-----+-----------+
Is there a simple query that can be written to do this for all rows? For one row i know how to insert it but how can i auto inert for multiple rows.

This might be what you're looking for: SELECT INTO.
Taken from the link:
INSERT INTO tbl_temp2 (fld_id)
SELECT tbl_temp1.fld_order_id
FROM tbl_temp1 WHERE tbl_temp1.fld_order_id > 100;

BEWARE!! This answer is good only if you want to perform the above requested action upon a new insertion. Otherwise, you will need a different strategy
you should have something like this:
Select all you values from school_images then foreach them:
foreach($result as $res) {
if($res['photo'] == 1) {
// see step 2
} else {
// see step 3
}
}
if you have the value 1 in school_photos then:
INSERT INTO school (the_photo, colum3) VALUES ($res['id'], $some_value)
if you don't have it, then perform a normal insert like you did by now.

You can also use inner join to achieve that.
Update School inner join school_images on School.id = school_images.school_id and photo=1
set the_photo = school_images.id ;

You should use an INNER JOIN to join school with school_images:
UPDATE
school INNER JOIN school_images
ON school.id = school_images.school_id
AND school_images.photo=1
SET
school.the_photo=school_images.id

UPDATE school AS s, school_images AS si SET s.the_photo = si.id WHERE s.id = si.school_id AND si.photo = 1;

Related

Shortening PHP code when comparing multiple MYSQL columns

I use lengths of code similar to this repeatedly in my scripting because I cannot find a shorter way to to compare the MYSQL columns
if ($them['srel1']=="Y" AND $me['Religion']=='Adventist'){$seek11pts=5;}
if ($them['srel2']=="Y" AND $me['Religion']=='Agnostic'){$seek11pts=5;}
if ($them['srel3']=="Y" AND $me['Religion']=='Atheist'){$seek11pts=5;}
if ($them['srel4']=="Y" AND $me['Religion']=='Baptist'){$seek11pts=5;}
if ($them['srel5']=="Y" AND $me['Religion']=='Buddhist'){$seek11pts=5;}
if ($them['srel6']=="Y" AND $me['Religion']=='Caodaism'){$seek11pts=5;}
if ($them['srel7']=="Y" AND $me['Religion']=='Catholic'){$seek11pts=5;}
if ($them['srel8']=="Y" AND $me['Religion']=='Christian'){$seek11pts=5;}
if ($them['srel9']=="Y" AND $me['Religion']=='Hindu'){$seek11pts=5;}
if ($them['srel10']=="Y" AND $me['Religion']=='Iskcon'){$seek11pts=5;}
if ($them['srel11']=="Y" AND $me['Religion']=='Jainism'){$seek11pts=5;}
if ($them['srel12']=="Y" AND $me['Religion']=='Jewish'){$seek11pts=5;}
if ($them['srel13']=="Y" AND $me['Religion']=='Methodist'){$seek11pts=5;}
if ($them['srel14']=="Y" AND $me['Religion']=='Mormon'){$seek11pts=5;}
if ($them['srel15']=="Y" AND $me['Religion']=='Moslem'){$seek11pts=5;}
if ($them['srel16']=="Y" AND $me['Religion']=='Orthodox'){$seek11pts=5;}
if ($them['srel17']=="Y" AND $me['Religion']=='Pentecostal'){$seek11pts=5;}
if ($them['srel18']=="Y" AND $me['Religion']=='Protestant'){$seek11pts=5;}
if ($them['srel19']=="Y" AND $me['Religion']=='Quaker'){$seek11pts=5;}
if ($them['srel20']=="Y" AND $me['Religion']=='Scientology'){$seek11pts=5;}
if ($them['srel21']=="Y" AND $me['Religion']=='Shinto'){$seek11pts=5;}
if ($them['srel22']=="Y" AND $me['Religion']=='Sikhism'){$seek11pts=5;}
if ($them['srel23']=="Y" AND $me['Religion']=='Spiritual'){$seek11pts=5;}
if ($them['srel24']=="Y" AND $me['Religion']=='Taoism'){$seek11pts=5;}
if ($them['srel25']=="Y" AND $me['Religion']=='Wiccan'){$seek11pts=5;}
if ($them['srel26']=="Y" AND $me['Religion']=='Other'){$seek11pts=5;}
EG: if ($them['srel1']=="Y" AND $me['Religion']=='Adventist'){$seek11pts=5;}
I check to seek if the MYSQL column srel1 has a value of Y. if it does then I check to see if the column Religion equals Adventist. If both are true then $seek11pts=5, if they are not both true then nothing happens.
There are 26 srel type columns with either a Y value or null. There are also 26 different values for Religion as you may see. This is but one section of my code. I have multiple HUGE code groupings like this and I'd love to be able to reduce it down to a few lines. I was thinking some kind of array for the religions and another for the numerical endings of the srel columns but I cant get it.
For this current code you can use this:
<?php
$religions = array(1 => 'Adventist','Agnostic','Atheist','Baptist','Buddhist','Caodaism','Catholic','Christian','Hindu','Iskcon','Jainism','Jewish','Methodist','Mormon','Moslem','Orthodox','Pentecostal','Protestant','Quaker','Scientology','Shinto','Sikhism','Spiritual','Taoism','Wiccan','Other');
$count = count($religions) + 1;
for ($i = 1; $i < $count; $i++) {
if ($them["srel$i"]=="Y" && $me['Religion']==$religions[$i]) {
$seek11pts=5;
break;
}
}
While there are ways to accomplish what you ask, you should instead seriously consider restructuring your data.
Better data structure
If your data had a structure more similar to the following:
db.person
+----+------+
| id | name |
+----+------+
| 1 | Nick |
| 2 | Bob |
| 3 | Tony |
+----+------+
PrimaryKey: id
db.religion
+----+---------+
| id | name |
+----+---------+
| 1 | Atheist |
| 2 | Jainism |
| 3 | FSM |
+----+---------+
PrimaryKey: id
db.person_religion
+--------+----------+
| person | religion |
+--------+----------+
| 1 | 2 |
| 2 | 2 |
| 2 | 3 |
| 3 | 1 |
| 3 | 2 |
| 3 | 3 |
+--------+----------+
UniqueIndex: (person,religion)
...everything you're trying to do could be done with simple queries.
SELECT me.id, me.name, meR.name as religion, count(them.id) as matches
FROM person me
LEFT INNER JOIN person_religion meRlookup
ON me.id = meRlookup.person
LEFT INNER JOIN religion meR
ON meRlookup.religion = meR.id
LEFT INNER JOIN person_religion themRlookup
ON meRlookup.religion = themRlookup.religion
LEFT INNER JOIN person them
ON themRlookup.person = them.id
GROUP BY meR.id
I would recommend using laravel or lumen, since these include a "queries generator" that just write a little code (NOTHING SQL) to make queries and that ..

for each value of one table get and display count number of coresponding values from another table

unfortunately i have to do this in mysql / php . I looked for three days, and there is like 10.000 explantions of this but NONE (and I repeat NONE) works for me. I tried it all. I have to ask, sorry.
I have two tables - articles and control.
table "articles"
------------------
art_id | name |
------------------
1 | aaa |
2 | bbb |
3 | ccc |
4 | ddd |
table "control"
--------------------------------------------
con_id | art_id | data |
--------------------------------------------
1 | 1 | something-a |
2 | 2 | something-b |
3 | 1 | something-a |
4 | 2 | something-c |
5 | 3 | something-f |
art_id exists in both tables. Now what i wanted - for query:
"select * from articles order by art_id ASC" displayed in a table
to have also one cell displaying the count for each of art_id's from table CONTROL...
and so i tried join, left join, inner join - i get errors ... I also tried for each get only one result (for example 2 for everything)... this is semi-right but it displays the array of correct results and it's not even with join!!! :
$query = "SELECT art_id, count(*) as counting
FROM control GROUP BY art_id ORDER BY con_id ASC";
$result = mysql_query($query);
while($row=mysql_fetch_array($result)) {
echo $row['counting'];
}
this displays 221 -
-------------------------------------------------
art_id | name | count (this one from control) |
-------------------------------------------------
1 | aaa | 221 |
2 | bbb | 221 |
3 | ccc | 221 |
and it should be:
for art_id(value1)=2,
for art_id(2)=2,
for art_id(3)=1
it should be simple - like a count of values from CONTROL table displayed in query regarding the "articles" table...
The result query on page for table articles should be:
"select * from articles order by art_id ASC"
-------------------------------------------------
art_id | name | count (this one from control) |
-------------------------------------------------
1 | aaa | 2 |
2 | bbb | 2 |
3 | ccc | 1 |
So maybe i should go with JOIN or with join plus for each... Tried tha too, but then i'm not sure what is the proper thing to echo... all-in-all i'm completely lost here. Please help. Thank you.
So imagine this in two steps:
Get the counts per art_id from the control table
Using your articles table, pick up the counts from step 1
That will give you a query that looks like this:
SELECT a.art_id, a.name, b.control_count
FROM articles a
INNER JOIN
(
SELECT art_id, COUNT(*) AS control_count
FROM control
GROUP BY art_id
) b
ON a.art_id = b.art_id;
Which will give you the results you're looking for.
However, instead of using a subquery, you can do it all in one shot:
SELECT a.art_id, a.name, COUNT(b.art_id) AS control_count
FROM articles a
INNER JOIN control b
ON a.art_id = b.art_id
GROUP BY a.art_id, a.name;
SQL Fiddle demo
SELECT *, (SELECT COUNT(control.con_id) FROM control WHERE control.art_id = articles.art_id) AS count_from_con FROM articles ORDER BY art_id DESC;
If I understood your question right, this query should do the trick.
Edit: Created the tables you have described, and it works.
SELECT * FROM articles;
+--------+------+
| art_id | name |
+--------+------+
| 1 | aaa |
| 2 | bbb |
| 3 | ccc |
| 4 | ddd |
+--------+------+
4 rows in set (0.00 sec)
SELECT * FROM control;
+--------+--------+------+
| con_id | art_id | data |
+--------+--------+------+
| 1 | 1 | NULL |
| 2 | 2 | NULL |
| 3 | 1 | NULL |
| 4 | 2 | NULL |
| 5 | 3 | NULL |
+--------+--------+------+
5 rows in set (0.00 sec)
SELECT *, (SELECT COUNT(control.con_id) FROM control WHERE control.art_id = articles.art_id) AS count_from_con FROM articles ORDER BY art_id ASC;
+--------+------+----------------+
| art_id | name | count_from_con |
+--------+------+----------------+
| 1 | aaa | 2 |
| 2 | bbb | 2 |
| 3 | ccc | 1 |
| 4 | ddd | 0 |
+--------+------+----------------+
You haven't quite explained what you want to accomplish with the print out but here is an example in PHP: (Use PDO instead of mysql_)
$pdo = new PDO(); // Make your connection here
$stm = $pdo->query('SELECT *, (SELECT COUNT(control.con_id) FROM control WHERE control.art_id = articles.art_id) AS count_from_con FROM articles ORDER BY art_id ASC');
while( $row = $stm->fetch(PDO::FETCH_ASSOC) )
{
echo "Article with id: ".$row['art_id']. " has " .$row['count_from_con'].' connected rows in control.';
}
Alternatively with the mysql_ extension:
$result = mysql_query('SELECT *, (SELECT COUNT(control.con_id) FROM control WHERE control.art_id = articles.art_id) AS count_from_con FROM articles ORDER BY art_id ASC');
while( $row = mysql_fetch_assoc($result) )
{
echo "Article with id: ".$row['art_id']. " has " .$row['count_from_con'].' connected rows in control.';
}
This should be enough examples to help you accomplish what you need.

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)

mySQL: Showing data from one table using id from another

I want my users to be able to make a favourite list.
I have two tables in a database in mySQL. One stores information about businesses and the other stores the unique user ids as well as the ids from the first table that the user has marked a favourite.
Table 1
<pre>
ID | NAME | EMAIL | PHONE |
1 | Joe | a#mail.com | 25634565 |
2 | John | b#mail.com | 43634565 |
3 | Jack | c#mail.com | 65634565 |
4 | James| d#mail.com | 43634565 |
5 | Julie| e#mail.com | 65634565 |
...
</pre>
Table 2
<pre>
USERID | FAV1 | FAV2 | FAV3 | FAV...
2565325489 | 1 | 3 | 5 |
8596854785 | 3 | 2 | NULL |
2356256263 | 5 | NULL | NULL |
...
</pre>
The output I want for a user (in this example the first in table2):
<pre>
Joe | a#mail.com | 25634565 |
Jack | c#mail.com | 65634565 |
Julie| e#mail.com | 65634565 |
</pre>
I have looked into JOIN LEFT and minus query calls, but I just can't make it work. I have a basic understanding of mySQL and PHP, but not a lot.
I would highly appreciate any help with what approach to take.
Ps. If there are better ways to structures my databases, I would love to know.
I'd use a table with two fields - userID and fav - make one entry for each entry. And then...
SELECT table1.name, table1.email, table1.phone FROM table1,table2 WHERE table2.fav = table1.id AND table2.userid = 2565325489
Select * from table1 InnerJoin (Select * from table2) as t4 on table1.ID=t4.FAV1
$result = mysqli_query('SELECT name,email,phone FROM t1 table1 LEFT JOIN table2 t2 ON t1.ID = t2.fav1');
//iterate the results
while ($row = mysqli_fetch_array($result))
{
echo $row['name']." ".$row['email']." "$row['phone'];
}

I need to create a query using MySQL and PHP to get a result of two tables

I'm new to MySQL and PHP. I have two tables, one to hold all the company names and the other table has only the company name below the user:
Table 1
| # | Company name |
--------------------
| 1 | Microsoft |
| 2 | HP |
| 3 | Asus |
| 4 | Apple |
| 5 | Amazon |
| 6 | CCN |
table 2
| # | Company name | User name |
--------------------------------
| 1 | Asus | x1 |
| 2 | Apple | x1 |
| 3 | HP | x2 |
| 4 | Asus | x2 |
| 5 | Apple | x2 |
I need to create a query that achieves the following. First of all the companies are shown which are associated with a specific user (say Asus and Apple for user x1). After that, the remaining companies from table 1 are shown.
For example, the result of the query I'm looking for, for user X1 will display the rows in this way:
| # | Company name |
--------------------
| 1 | Asus |
| 2 | Apple |
| 3 | Microsoft |
| 4 | HP |
| 5 | Amazon |
| 6 | CCN |
How can I achieve this?
It looks like you want to include all companies, but for a given user, list the companies associated with that user first. If that's the case, you do not want to use an INNER JOIN.
Here's some SQL that should work. I've provided reasonable table and field names since you didn't give those. I'm also assuming that you have a reasonably sane table design with no duplicate rows.
SELECT c.company_name,
CASE
WHEN u.company_name IS NULL THEN 'N'
ELSE 'Y'
END AS user_has_company
FROM companies c
LEFT JOIN (
SELECT *
FROM users
WHERE user_name = 'x1'
) u
ON u.company_name = c.company_name
ORDER BY user_has_company DESC, c.company_name
This query will return an extra column - user_has_company. I'd use that to indicate whether the current user is associated with a given company, but you can ignore it if you want.
You will need a JOIN Statement to join another in the SELECT-Statement of table1
Quick example:
SELECT * FROM table2 INNER JOIN table1.id = table2.id WHERE table2.username = 'x1'
You'll find everything you need in the Documentation of JOINs.
http://dev.mysql.com/doc/refman/5.1/en/left-join-optimization.html
If you're just after the MySQL query for this then something like this would work
SELECT company_name,SUM(IF(user_name='x1',1,0)) as ordering
FROM `table2`
GROUP BY company_name
ORDER BY ordering DESC
But you should look at your schema before you go much further. If you have a column (company_name) in one table that refers to another table you should make that column refer to the PRIMARY KEY of the other table, i.e.
Table1
| # | company_name |
--------------------
| 1 | microsoft |
| 2 | hp |
| 3 | asus |
| 4 | apple |
| 5 | amazon |
| 6 | CCN |
table2
| # | company_id | user_name |
--------------------------------
| 1 | 3 | x1 |
| 2 | 4 | x1 |
| 3 | 2 | x2 |
| 4 | 3 | x2 |
| 5 | 4 | x2 |
This is one of the first things you learn in database design/normalisation. You will need to change your query in this case. Something like this:
SELECT company_name,SUM(IF(user_name='x1',1,0)) as ordering
FROM `table1`
LEFT JOIN `table2` ON table2.company_id=table1.id
GROUP BY company_name
ORDER BY ordering DESC
Create your query like this:
$sql = "SELECT b.companyName FROM table1 a INNER JOIN table2 b ON a.companyName = b.companyName WHERE b.userName = 'x1'";
Then, using PHP, use:
$con = mysql_connect("localhost","peter","abc123");
if (!$con)
{
die('Could not connect: ' . mysql_error());
}
mysql_select_db("my_db", $con);
$result = mysql_query($sql);
while($row = mysql_fetch_array($result))
{
echo $row['companyName'];
echo "<br />";
}
mysql_close($con);
Try this query:
SELECT company_name FROM table2 ORDER BY user_name ASC
In the HTML table, using PHP code:
$result = mysql_query(" SELECT company_name, user_name FROM table2 ORDER BY user_name ASC");
echo "<table>
<tr><th>Company Name</th><th>username</th></tr>";
while($row = mysql_fetch_array($result) {
echo "<tr><td>{$row['company_name']}</td><td>{$row['user_name']}</td></tr>";
}
echo "</table>"

Categories