I select data from table A and what I want is to insert that data using a loop.
Here's my code:
$getlvls = "SELECT * FROM `access_chart` WHERE `ac_id`='$data->ac_id'";
$qry99 = $con->query($getlvls);
while($row = $qry99->fetch_assoc()) {
$lvl1 = $row['lvl1'];
$lvl2 = $row['lvl2'];
$lvl3 = $row['lvl3'];
$lvl4 = $row['lvl4'];
}
for($jaa = 1; $jaa <=4; $jaa++){
$auth_id = '$lvl'+$jaa;
$sql1 = "INSERT INTO `overtime_log`(`ot_id`, `lvl`, `user_id`) VALUES('$ot_id', $jaa, '$auth_id')";
$qry = $con->query($sql1);
}
I don't include all of my codes. Everything works, except for inserting the column $lvl1, $lvl2, $lvl3 and $lvl4 using a loop. Or if you would suggest other logic that's find.
Thanks in advance.
EDITED
Select the data:
|----------------|
|--access_chart--| TABLE
|----------------|
-------------------
|---------|---------------|--------|--------|--------|--------|
|--ac_id--|--access_name--|--lvl1--|--lvl2--|--lvl3--|--lvl4--|
|---------|---------------|--------|--------|--------|--------|
| 1 | MIS Dept | 4 | 5 | 9 | 0 |
This might be the output after INSERT QUERY:
|----------------|
|--overtime_log--| TABLE
|----------------|
-------------------
|---------|-------|-----------|
|--ot_id--|--lvl--|--user_id--|
|---------|-------|-----------|
| 1 | 1 | 4 |
| 1 | 2 | 5 |
| 1 | 3 | 9 |
| 1 | 4 | 0 |
Not sure where $ot_id is defined, but assuming you're using only ids and SQL injection isn't a concern, you could use something like:
$getlvls = "SELECT * FROM `access_chart` WHERE `ac_id`='$data->ac_id'";
$qry99 = $con->query($getlvls);
while($row = $qry99->fetch_array())
{
foreach(array(1=>$row['lvl1'],2=>$row['lvl2'],3=>$row['lvl3'],4=>$row['lvl4']) as $key=>$lvl)
{
$sql1 = "INSERT INTO `overtime_log`(`ot_id`, `lvl`, `user_id`) VALUES('$ot_id', $key, '$lvl')";
$qry = $con->query($sql1);
}
}
Alternatively you could avoid the inner loop altogether and just write the INSERT using multiple-insert syntax:
$getlvls = "SELECT * FROM `access_chart` WHERE `ac_id`='$data->ac_id'";
$qry99 = $con->query($getlvls);
while($row = $qry99->fetch_array())
{
$con->query("INSERT INTO `overtime_log`(`ot_id`, `lvl`, `user_id`)
VALUES('$ot_id', 1, '{$row['lvl1']}'),
('$ot_id', 2, '{$row['lvl2']}'),
('$ot_id', 3, '{$row['lvl3']}'),
('$ot_id', 4, '{$row['lvl4']}')");
}
Related
I have a table named users with a column called user_subs. It looks like this.
In user_subs I have stored the specific users session username. Lets say this specific users name is James.
Now how would I loop through a specific user_subs looking for "James" and remove him from that specific user_subs without removing all the other names.
This is what I have so far and the only problem is, its deleting all the usernames in user_subs instead of just "James".
if(isset($_GET['p_id'])) {
$the_post_id = $_GET['p_id'];
$the_post_author = $_GET['author'];
}
if(isset($_POST['delete_sub'])) {
$username = $_SESSION['username'];
$query = "SELECT user_subs FROM users WHERE username = '{$username}' ";
$select_users_by_id = mysqli_query($connection, $query);
while ($row = mysqli_fetch_array($select_users_by_id)) {
$user_subs = explode(',', $row['user_subs']);
foreach($user_subs as $out) {
$query = "UPDATE users SET user_subs = null WHERE username = '{$the_post_author}' ";
$unsubscribe_user = mysqli_query($connection, $query);
echo "Unsubscribed";
}
}
}
THIS IS JUST IN TEST, PREPARED STATEMENTS WILL BE USED BEFORE GOING LIVE
Thank you for your time.
I second the other user's comment about moving this column to a different table. In the meanwhile, if you want to achieve what you are asking for, you can try removing the user name from the column value and update it with the remaining text.
if(isset($_POST['delete_sub'])) {
$username = $_SESSION['username'];
$query = "SELECT user_subs FROM users WHERE username = '{$username}' ";
$select_users_by_id = mysqli_query($connection, $query);
while ($row = mysqli_fetch_array($select_users_by_id)) {
$user_subs = str_replace($username . ',', '', $row['user_subs']);
$query = "UPDATE users SET user_subs = '{$user_subs}' WHERE username = '{$the_post_author}' ";
$unsubscribe_user = mysqli_query($connection, $query);
echo "Unsubscribed";
}
}
OPTION-2
$user_subs = explode(',', $row['user_subs']);
$user_subs_new = [];
foreach($user_subs as $out) {
if ($out !== $username) {
$user_subs_new[] = $out;
}
}
$user_subs = implode(',',user_subs_new);
$query = "UPDATE users SET user_subs = '{$user_subs}' WHERE username = '{$username}' ";
$unsubscribe_user = mysqli_query($connection, $query);
echo "Unsubscribed";
}
Let's start over. Let's start here, in fact...
DROP TABLE IF EXISTS users;
CREATE TABLE users
(user_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
,email VARCHAR(20) NOT NULL UNIQUE
);
DROP TABLE IF EXISTS user_subs;
CREATE TABLE user_subs
(user_id INT NOT NULL
, sub_id INT NOT NULL
, active TINYINT NOT NULL DEFAULT 1
, PRIMARY KEY(user_id,sub_id)
);
INSERT INTO users VALUES
(1,'b.smyth634#gmail.com'),
(2,'james#gmail.com'),
(3,'f#gmail.com'),
(4,'sally#gmail.com'),
(5,'thomas#gmail.com');
INSERT INTO user_subs (user_id,sub_id) VALUES
(1,5),
(1,2),
(1,1),
(1,4),
(2,1),
(2,2),
(2,4);
SELECT * FROM users;
+---------+----------------------+
| user_id | email |
+---------+----------------------+
| 1 | b.smyth634#gmail.com |
| 2 | james#gmail.com |
| 3 | f#gmail.com |
| 4 | sally#gmail.com |
| 5 | thomas#gmail.com |
+---------+----------------------+
SELECT * FROM user_subs;
+---------+--------+--------+
| user_id | sub_id | active |
+---------+--------+--------+
| 1 | 5 | 1 |
| 1 | 2 | 1 |
| 1 | 1 | 1 |
| 1 | 4 | 1 |
| 2 | 1 | 1 |
| 2 | 2 | 1 |
| 2 | 4 | 1 |
+---------+--------+--------+
SELECT u.*
, GROUP_CONCAT(us.sub_id) subs
FROM users u
JOIN user_subs us
ON us.user_id = u.user_id
GROUP
BY u.user_id;
+---------+----------------------+---------+
| user_id | email | subs |
+---------+----------------------+---------+
| 1 | b.smyth634#gmail.com | 1,2,4,5 |
| 2 | james#gmail.com | 1,2,4 |
+---------+----------------------+---------+
From here we have a choice. We can either DELETE subs we no longer wish to consider, or simply UPDATE them as 'inactive'.
Either way, we just need a DELETE or an UPDATE. So no SELECT needed. In fact a SELECT would, as I mentioned, be counterproductive - because a user may modify the data set in between the execution of the SELECT and the execution of the UPDATE/DELETE. This is known as a 'race condition'.
I have a table like this:
// mytable
+----+---------+------------+
| id | id_post | code_table |
+----+---------+------------+
| 1 | 34523 | 1 |
| 2 | 3453 | 4 |
| 3 | 43434 | 2 |
| 4 | 54321 | 1 |
| 5 | NULL | NULL |
| 6 | 32411 | 2 |
| 7 | 42313 | 1 |
| 8 | 34242 | 2 |
+----+---------+------------+
// ^ all of my focus is on this column
Also I have this array:
$convert_code_name = array (
"1" => "Post1",
"2" => "Post2",
"3" => "Post3",
"4" => "Post4"
);
Now I want to create this:
$query = "select * from post1
union all
select * from post2
union all
select * from post4";
// there isn't "post3", because 3 isn't exist in the code_table column
How can I do that?
Here is my try:
// connect to database
$stm = $db->prepare('select * from mytable');
$stm->execute();
$result = $stm->fetch();
/* array_unique: removes duplicate values
array_filter: removes "NULL" values */
array_filter(array_unique($result[code_table]), function($item) {
return $item != 'NULL';
});
foreach($item as $numb){
$query .= 'select * from'.$convert_code_name[$numb].'union all';
}
But I don't know why my code doesn't work, How can I do that?
First, use SELECT DISTINCT in the query to get unique values, so you don't need to call array_unique.
Then, once you have all the values, you can use implode to connect all the SELECT queries with UNION ALL.
$stm = $db->prepare("SELECT DISTINCT code_table FROM mytable WHERE code_table IS NOT NULL");
$stm->execute();
$results = $stm->fetchAll();
// This returns a 2-dimensional array, we just want one column
$results = array_column($results, 'code_table');
$query = implode(' UNION ALL ', array_map(function($code_table) use ($convert_code_name) {
return "SELECT * FROM " . $convert_code_name[$code_table];
}, $results));
$query .= 'select * from'.$convert_code_name[$numb].'union all';
will generate wrong sql, change it to (I assume that $convert_code_name[$numb] contains full table name like Post1, Post2):
$query = '';
foreach($item as $numb){
$query .= ($query!=''?' union all ':'') . 'select * from '.$convert_code_name[$numb];
}
You simply need to first execute this query:
SELECT DISTINCT code_table FROM events
Then you can build your second query like from its result, which only contains 1 row for each existing code_table.
I do a simple SQL-Query:
SELECT `name`, `likes`
FROM `social`
WHERE `month` = '2015-01'
ORDER BY `likes` DESC
then I add a "Rank" wich is an intenger with ++
$data = array();
$rank = 0;
while ($table_row = mysqli_fetch_assoc($table)) {
$rank++;
$data[$table_row['name']] = $table_row;
$data[$table_row['name']]['rank'] = $rank;
}
The result is left and what I want on the right side
+------+------+-------+ +------+------+-------+
| rank | name | likes | | rank | name | likes |
+------+------+-------+ +------+------+-------+
| 1 | foo | 123 | | 1 | foo | 123 |
| 2 | mfoo | 33 | | 2 | mfoo | 33 |
| 3 | xfoo | 33 | | 2 | xfoo | 33 |
| 4 | yfoo | 30 | | 4 | yfoo | 30 |
| 5 | zfoo | 29 | | 5 | zfoo | 29 |
+------+------+-------+ +------+------+-------+
how do I get the right side table? is there a way to solve it in the query?
EDIT:
There I am standing now:
select IF(#likes=s.likes, #rownum, #rownum:=#rownum+1) rank2,
s.domain_name, s.likes,
(#likes:=s.likes) dummy
from social s,
(SELECT #rownum:=0) x,
(SELECT #likes:=0) y
WHERE `month` = '2015-01'
order by likes desc
but the rank is not 100% correct because I want to skip a rank instead of counting through
I see what's happening here.
I dont know about best practices but I'd probably do something like this myself:
$data = array();
$rank = 0;
$lastlike = 1;
$currentlike = 0;
$i = 0;
while ($table_row = mysqli_fetch_assoc($table)) {
$name = $table_row['name'];
$currentlike = $table_row['likes'];
if ($currentlike != $lastlike) $rank++;
$data[$i] = array('rank'=>$rank,'name'=>$name,'likes'=>$currentlike);
$lastlike = $currentlike;
$i++;
}
I've not checked it but you're welcome to try it out and see.
You can do this with SQL or with PHP (you can test to know which one is the faster).
Note : this 2 solutions will give you a rank which start at 0.
SQL :
SELECT
`name`,
`likes`,
(SELECT COUNT(*) FROM `social` AS S2 WHERE S1.likes > S2.likes) AS `rank_2`
FROM `social` AS S1
WHERE `month` = '2015-01'
ORDER BY `likes` DESC
PHP :
$data = array();
$rank = 0;
$likes_pre = -1;
while ($table_row = mysqli_fetch_assoc($table)) {
$likes_cur = $table_row['likes'];
if ($likes_pre > $likes_cur) {
$rank++;
}
$data[$table_row['name']] = $table_row;
$data[$table_row['name']]['rank'] = $rank;
$likes_pre = $likes_cur;
}
Not tested, but it should work.
Try this... rank should be the same for all rows with the same number of likes
$data = array();
$rank = 0;
$last_likes =0;
while ($table_row = mysqli_fetch_assoc($table)) {
if ($last_likes != $row['likes']) {
$rank++;
}
$data[$table_row['name']] = $table_row;
$data[$table_row['name']]['rank'] = $rank;
}
I need to count how many times in ripeted the same values in different columns for the same id..
I'll try to clarify with an example:
TABLE:
+-----+-----+-----+-----+-----+
| id | d01 | d02 | d03 | d04 |
+=====+=====+=====+=====+=====+
| 1 | A | A | B | B |
+-----+-----+-----+-----+-----+
| 2 | A | A | A | A |
+-----+-----+-----+-----+-----+
| 3 | B | B | A | A |
+-----+-----+-----+-----+-----+
| 4 | A | A | A | A |
+-----+-----+-----+-----+-----+
| 5 | A | A | A | A |
+-----+-----+-----+-----+-----+
| 6 | B | A | A | A |
+-----+-----+-----+-----+-----+
I need to know how many times the value "B" is repeating for any person (ID)..
Is that possible to do that? RESULTS
+-----+-----+-----+
| id | count B |
+=====+=====+=====+
| 1 | 2 |
+-----+-----+-----+
| 2 | 0 |
+-----+-----+-----+
| 3 | 2 |
+-----+-----+-----+
I was thinking to use the function "SUM" but I have no idea how to display just the single ID.
Thanks in advance, hope the question is clear enough!
If there are only four columns:
SELECT id, (d01 = 'B') + (d02 = 'B') + (d03 = 'B') + (d04 = 'B')
FROM tablename
No there are 31 columns
That's a problem which you can solve in two ways:
Repeat the condition for the other 27 columns :)
Normalize your structure so that each value is dependent on both the id and a numeric value that represents a calendar.
The PHP way
You can also fetch all columns and let PHP solve this for you:
$res = $db->query('SELECT * FROM tablename');
foreach ($res->fetchAll(PDO::FETCH_ASSOC) as $row) {
$id = $row['id'];
unset($row['id']); // don't count the id column
$count = count(array_keys($row, 'B', true));
printf("ID %d: %d\n", $id, $count);
}
Since you seem to be using mysql_*:
// SHOW COLUMNS returns all the columns and constrains of the defined table
// We only need the column names so we will be later calling it by 'Field'
$sql = mysql_query("SHOW COLUMNS FROM table"); //your table name here
$val_to_count = 'B'; //value to count here
$id = 1; //id to search for
$new_sql = 'SELECT id, ';
// In this loop we will construct our SELECT query using the columns returned
// from the above query
while($row=mysql_fetch_array($sql)){
if($row['Field']!='id'){
$new_sql .= ' ('.$row['Field'].' = "'.$val_to_count.'") + ';
}
}
//Removing the last "+ " produced in the select query
$new_sql = rtrim($new_sql,"+ ");
$new_sql .= ' as count FROM table WHERE id = '.$id; //table name here again
// so $new_sql now has an output like:
// SELECT ID, (d01 = 'B') + (d02 = 'B') ... WHERE id = 1
$sql2 = mysql_query($new_sql);
//executing the constructed query with the output below
while($row2=mysql_fetch_array($sql2)){
echo 'ID - '.$row2['id']."<br>";
echo 'Count - '.$row2['count']."<br>";
}
Note:
mysql_* is deprecated, please consider to migrate to mysqli_*
I have a query like so:
SELECT * FROM `purchases` p
JOIN `purchase_types` pt ON p.purchase_type = pt.node
When I run it in PHPmyAdmin it returns the proper result set like so:
node | purchase_type | amount_spent | node | name
--------------------------------------------------
2 | 5 | 8.5000 | 5 | Lunch
3 | 5 | 1.5000 | 5 | Lunch
4 | 6 | 4.6600 | 6 | Dinner
This is my PHP code:
$sql = "SELECT * FROM `purchases` p
JOIN `purchase_types` pt ON p.purchase_type = pt.node";
$query = mysql_query($sql);
$result = mysql_fetch_assoc($query);
$purchases = array();
while($row = mysql_fetch_assoc($query)) {
$purchases[] = array(
'name' => $row['name'],
'amount_spent' => $row['amount_spent']
);
}
for eaching over $expenses returns the following output:
3 | 5 | 1.5000 | 5 | Lunch
4 | 6 | 4.6600 | 6 | Dinner
What happens to the first "Lunch"? How can I have the PHP output be the same as the direct MySQL query output?
You call mysql_fetch_accoc before while. Don't.
You should also realize that ext/mysql will be deprecated and upgrade your code to use properly parameterized queries with PDO or mysqli
try with mysql_fetch_array,
$purchases = array();
while($row = mysql_fetch_array($query)) {
$purchases[] = $row;
}
if you want to get data just do
foreach($purchases as $key => $value)
{
$name = $value['name'];
$amount_spent = $value['amount_spent'];
echo 'name : '.$name.' , amount spent '.$amount_spent.'<br />';
}