Update a mysql table based on another. Complicated query - php

Short about my tables: I have 2 tables: content, users
content structure is something like:
id | title | cpc | user | active
users is:
id | user | monetos
Idea - I want to select contet.* rows which have content.active = 1 (n). Having this data, SELECT users.monetos WHERE users.id=content.user from previous query.
And now, by maximum (n) steps i decrement users.monetos value by content.cpc value
and on the moment when *users.monetos=0 or less than 0, i want to update content and SET active='0'*
By words, i want like to share users.monetos amount to each content entry (content.cpc for each). And there's no more users.monetos make the current content
entry inactive. And do this vor every content.user
What i'he done at this moment is shown below. I now it looks really bad, but i already don't know what to do. Count on you guys. Thank you.
$kak2 = array();
$rs16 = $connector->query("SELECT user FROM content WHERE active='1'");
while($rw16 = $connector->fetchArray($rs16))
{
$users_ids[] = $rw16['user'];
}
$user_info2 = $connector->fetchArray("SELECT monetos,id FROM users WHERE id IN (".implode(',',$users_ids).")");
while($user_info = $connector->fetchArray($user_info2))
{
$current_entry_info2 = $connector->query("SELECT cpc,id FROM content WHERE user='$user_info[id]' ORDER BY date DESC");
while ($current_entry_info = $connector->fetchArray($current_entry_info2))
{
$user_info['monetos']= $user_info['monetos'] - $current_entry_info['cpc'];
if($user_info['monetos'] = 0)
{
$updt = $connector->query("UPDATE content SET active='0' WHERE id='$current_entry_info[id]' LIMIT 1");
}
}
}

I think i have got the idea of what you are trying to do so have contructed a small code snippit which i think should do what you are after.
note this is untested code
/** get the cost of all content for all users **/
$query = "select b.id, sum(a.cpc) as cpc from content a
join users b on a.user= b.id
group by b.id where a.active = 1"
/** cycle each user **/
foreach($rows = $connector->fetchArray($query) as $row ) {
$menotos = $row['cpc'];
$query = "select id, cpc from content where user={$row['id']}"
/** cycle each users content **/
foreach($contents = $connector->fetchArray($query) as $content) {
$menotos -= $content['cpc'];
if($menotos <= 0) {
$disable[] = $content['id'];
}
}
if( isset($disable) ) {
$connector->query("update content set active=0 where id in(" . implode(',', $disable) . ")";
}
}

Related

Looping through a loop each result gives multiple incorrect results

I have been scratching my head for a very long time about this PHP code. I am trying to achieve something like
->Get each status
->Get each user in user's friends list
->Display status' from each user that is in the user's friends list
and repeat until there is no more. I have been looking for a solution for more a few days and it is really bugging me. Here is the code I tried:
EDIT: posted schema as requested
https://kjf-tech.net/files/schema.png
<?php
$connect = new MySQLi($DBhost,$DBuser,$DBpass,$DBname);
$querya = "SELECT * FROM statuses ORDER BY `id` DESC";
$result = mysqli_query($connect, $querya);
$ALLDATA = array();
$DBcon2 = new MySQLi($DBhost,$DBuser,$DBpass,$DBname);
if ($DBcon2->connect_errno) {
die("ERROR : -> ".$DBcon2->connect_error);
}
while ($record = mysqli_fetch_array($result, MYSQLI_ASSOC)) {
array_push($ALLDATA, $record);
$queryb = "SELECT * FROM friendslist WHERE idOfPerson1='".$record['idOfUser']."' OR idOfPerson2='".$record['idOfUser']."' OR idOfPerson2='".$userRow['user_id']."' OR idOfPerson1='".$userRow['user_id']."' ORDER BY `id` DESC";
$result2 = mysqli_query($connect, $queryb);
$ALLDATA2 = array();
while ($record2 = mysqli_fetch_array($result2, MYSQLI_ASSOC)) {
array_push($ALLDATA2, $record2);
if($record['idOfUser'] == $userRow['user_id']) {
echo '<div>You Posted on '.$record['whenPosted'].'<br />'.$record['content'].'</div>';
}
elseif($record2['idOfPerson1'] == $userRow['user_id']) {
$query2 = $DBcon2->query("SELECT * FROM tbl_users WHERE user_id='".$record2['idOfPerson2']."'");
$userRow2=$query2->fetch_array();
echo '<div>'.$userRow2['username'].' Posted on '.$record['whenPosted'].'<br />'.$record['content'].'</div>';
}
elseif($record2['idOfPerson2'] == $userRow['user_id']) {
$query2 = $DBcon2->query("SELECT * FROM tbl_users WHERE user_id='".$record2['idOfPerson1']."'");
$userRow2=$query2->fetch_array();
echo '<div>'.$userRow2['username'].' Posted on '.$record['whenPosted'].'<br />'.$record['content'].'</div>';
}
}
mysqli_free_result($result2);
}
$DBcon2->close();
mysqli_free_result($result);
?>
Your schema looks good, but let's take another look at the relations. I'm going to rename some of the columns for convenience.
Users:
+- user_id
| user_name
|
|
| Friendships:
| fid
+- user_id
| friend_id --------+
| friendship_start |
| |
| |
| Statuses: |
| sid |
+- user_id ----------+
post_date
content
If you just wanted to find statuses of your friends, the query would look thus:
SELECT statuses.content
FROM friendships, statuses
WHERE friendship.user_id=? AND
friendships.friend_id = statuses.user_id
You would, of course, bind the appropriate user_id value when you ->prepare() the statement.
(See http://php.net/manual/en/mysqli.prepare.php for the proper way to do sql. You don't ever want to do something like mysql_query("select * from table where id=".$_POST['id']) because it's open to SQL injection)
Unfortunately, though, this does not include your own status in the query results. We'll have to do a little more work on the query...
SELECT statuses.content
FROM friendships, statuses
WHERE
( friends.user_id = ? AND
friends.friend_id = stuatuses.user_id )
OR
statuses.user_id = ?
ORDER BY statuses.post_date DESC
So far, so good... but we don't have the names nor the post date. The post date is easy, just add that to the select:
SELECT statuses.content, statuses.post_date
To add the name, we have to get data from Users also.
SELECT users.user_name, statuses.content, statuses.post_date
FROM users, friendships, statuses
WHERE
users.user_id = ? AND
(
( users.user_id = friendships.user_id AND
friendships.friend_id = statuses.user_id )
OR
statuses.user_id = users.user_id
)
ORDER BY statuses.post_date DESC
And there you have it; the database does all the work for you. No need for nested queries and such. This will just give you the simple list to print on your page. Please keep in mind that this is off the top of my head, so you may have to tweak it if I overlooked something.

Is there an efficient way to search variable parameters in mySQL with different results?

I have quite a complex question and due to the specifications I've had no luck finding any help with this. Scratching my head for a few months.
I have multiple parameters however in this question I'll focus on only 3
Category ($cat)
Subcategory ($sub)
Genre ($gen)
MySQL columns:
id | category | subcategory | genre | account | date_received | date_modified
(Account is assigned: 1-3)
I would like the results to return:
if only Category is offered:
first the row account = 1, then date_received, followed by date_modified (give no preference to accounts 2 & 3)
if only Category AND Subcategory is offered:
first the row account = 1 and account = 2, then date_received, followed by date_modified (give no preference to account 3)
if only Category AND Subcategory AND genre is offered:
first the row account = 1 and account = 2 and account = 3, then date_received, followed by date_modified
So far I have this:
if ($cat AND empty($sub) AND empty($gen)) {
$run = mysql_query("SELECT *
FROM db
WHERE (category='$cat')
ORDER BY case when account = '1' then 1 else 2 end,
GREATEST(date_received, modified_date, account) DESC ");
} else if ($cat AND $sub AND empty($gen)) {
$run = mysql_query("SELECT *
FROM db
WHERE (category='$cat' AND subcategory='$sub')
ORDER BY case when account = '2' then 1 else 2 end,
GREATEST(date_received, modified_date, account) DESC
");
} else if ($cat AND $sub AND $gen) {
$run = mysql_query("SELECT *
FROM db
WHERE (category='$cat' AND subcategory='$sub' AND genre='$gen')
ORDER BY case when account = '3' then 1 else 2 end,
GREATEST(date_received, modified_date, account) DESC
"); }
Is there an efficient way of combing these and echoing the different results?
It feels really messy.
Many thanks everyone for any tips you can offer.
Put all the conditions in an array, and the preferred account in a variable.
$conds = array();
if ($cat) {
$account = 1;
$conds[] = "category = '$cat'";
}
if ($sub) {
$account = 2;
$conds[] = "subcategory = '$sub'";
}
if ($gen) {
$account = 3;
$conds[] = "genre = '$gen'";
}
if (!empty($conds)) {
$cond_str = implode(' AND ', $conds);
$sql = "SELECT *
FROM db
WHERE $cond_str
ORDER BY IF(account = $account, 1, 2),
GREATEST(date_received, modified_date, account) DESC";
$run = mysql_query($sql);
...
}

MySQL complicated query. Dynamically Update rows from a table based on another

Above is a scheme I drew. There's an ideal case, when content.user are grouped. But usually they are not grouped.
What i meant in this scheme is:
At the first step, I select users.monetos WHERE users.id = content.user
At the second step, I decrement users.monetos with every content.cpc value (2.1 , 2.2)
When simulating this:
select content.user (9)
select users.monetos Where users.id=content.users (15)
So we have 15 value for users.monetos for users.id=9, now we go back to content table
and:
decrement 15 value with 8 (content.cpc) (15-8=7 > 0 -> go to step 2)
decrement 7 (result from previous step) with 10 (content.cpc) (7-10=-3 <0 -> update
content set active='0' where content.id= (current id when a negative result obtained) )
And like this for every content.user
More extended - I want to select contet.* rows which have content.active = 1 (n). Having this data, SELECT users.monetos WHERE users.id=content.user from previous query.
And now, by maximum (n) steps I decrement users.monetos value by content.cpc value
and on the moment when **users.monetos=0 or less than 0, i want to update content and SET active='0'**
By words, I want like to share users.monetos amount to each content entry (content.cpc for each). And there's no more users.monetos make the current content
entry inactive. And do this vor every content.user
What i'he done at this moment is shown below. I now it looks really bad, but I already don't know what to do.
$query = "select content.id, content.cpc, conent.user, content.active from content a
join users b on a.user=b.id
group by b.id where a.active='1'";
/** cycle each user **/
foreach($rows = $connector->fetchArray($query) as $row ) {
$monetos = $row['monetos'];
$query = "select id, cpc from content where user={$row['id']}";
/** cycle each users content **/
foreach($contents = $connector->fetchArray($query) as $content) {
echo $monetos;
$monetos -= $content['cpc'];
if($monetos <= 0) {
$disable[] = $content['id'];
}
}
if( isset($disable) ) {
$connector->query("update content set active='0' where id in(".implode(',',$disable).")");
}
}
You can try this code:
$query = "select * from users";
foreach($rows = $connector->fetchArray($query) as $row ) {
$a='';
$query = "select * from content where user='{$row[id]}' and active='1' ";
foreach($contents = $connector->fetchArray($query) as $content ) {
$a++;
$a_min=$a-1;
$test[$a]=$row[monetos]-$content[cpc];
if($a==2){
if($test[$a_min] > 0){
$test2=$test[$a_min]-$content[cpc];
if($test2 < 0){
$connector->query("update content set active='0' where id='$content[id]'");
}
}
}
}
}

How to get a session value from a second table?

I have two tables for the users; a login table and the user profile table.
I want to compare a value from 'userprofiletable' to another value from another table called posts. If the value is equal, it shows a list.
I have the following code. The problem is that it is not comparing the value in the posts table with the value of the session from user profile table.
Could someone help me please?
<?php
$limit = '5';
$dbreq = 'SELECT * FROM `posts` ORDER BY `pos` DESC';
$dbdata = mysql_query($dbreq);
while($dbval = mysql_fetch_array($dbdata))
{
if (($dbval['city'] == $_SESSION['student_city'])) { //checks for last 4 accomodation
if ($limit >= '1') {
echo '<tr><td>'.$dbval['title'].'</td></tr>';
$limit = $limit -'1';
}
}
}
?>
I also want to get the value of userprofiletable and post it in the posts table. For example, when somebody make a new post.
Your post is a bit unclear, but I think this is what you want:
<?php
$userid = 11542;//Sample uid. You will have to figure this out and set it.
$limit = 5;
$dbreq = "SELECT * FROM `posts` WHERE `userid`=".$userid." ORDER BY `pos` DESC LIMIT=".$limit.";";
$dbdata = mysql_query($dbreq);
while($dbval = mysql_fetch_array($dbdata))
{
if (($dbval['city'] == $_SESSION['student_city'])) { //checks for last 4 accomodation
echo '<tr><td>'.$dbval['title'].'</td></tr>';
}
}
?>
The question is not clear, but there could be two answers:
To reproduce your code, you can do in ONE sql query:
$dbreq = 'SELECT *
FROM `posts`
WHERE city="'.mysql_real_escape_string($_SESSION['student_city']).'"
ORDER BY `pos` DESC
LIMIT 4';
If, however, there are two tables, then you need "LEFT JOIN" linking the posts table to the userprofile table
$dbreq = 'SELECT p.*, u.*
FROM posts p
LEFT JOIN userprofiletable up ON p.UserID=up.UserID
WHERE up.city="'.mysql_real_escape_string($_SESSION['student_city']).'"
ORDER BY p.pos DESC
LIMIT 4';
(UserID in the table above is the name of the field in the posts table and userprofiletable that links the two.)

Searching for unread posts in a database

Everytime a user reads a post, it assigns a cookie, eg.
set_cookies($id,'read',60*60*24);
But the problem is how do i select all the posts that hasn't been read by the user?
SELECT * from posts where (post is unread)
It doesn't require a login. Table structure:
ID | Content | Category
With your solution, you'd do something like this:
$ids = array();
if (isset($_COOKIES)) {
foreach ($_COOKIES as $cookie => $value) {
if (is_numeric($cookie) && $value == 'read') {
$ids[] = $cookie;
}
}
}
if (isset($ids[0])) {
$posts = implode(',',$ids);
$query = "SELECT * from posts where id in ({$posts})";
// Do the query
} else {
// no read posts.
}
But you should really look into storing your read variables differently.
I am assuming here that when user reads a post the id of the post read is stored somewhere. Let's for the moment assume that it is in the table read_posts that has a format:
UID | ID
In this case your query becomes:
SELECT * FROM posts WHERE ID NOT IN (SELECT id FROM read_posts WHERE uid = <user's id>);
If you only allow reading sequentially and store data in the same table the query becomes even simpler:
SELECT p.* FROM posts p, read_posts rp WHERE p.ID > rp.ID AND rp.UID = <user id>;
Syntax on this query might vary slightly but the general idea I think is clear.
If you can create a list of ids that have been read, yes:
SELECT *
FROM posts
WHERE ID NOT IN ($list_of_post_ids_that_have_been_read)

Categories