I have a page that has a column "order". When I add a new item the order should be 1 + max of the item. But if I delete an item between these values like i have 8 9 10 , if I delete item with 9 the new item will have 11 value and I will have 8 10 11.But I want 8 9 10. How can I do this in php? should I create a function? It works to add a new item with the max+1, but if I delete is not good.
My code:
$queryMaxOrd = mysql_query("select max(ord) from article where user_id=" .$_SESSION['userId']);
$row = mysql_fetch_row($queryMaxOrd);
$valueMaxOrd = $row[0] + 1;
$_SESSION['a'] = $valueMaxOrd;
and the insert query....
Any ideas?
First thing to consider is removing mysql_* and start using mysqli_* or pdo. Your code is vulnerable to sql injections.
With your code structure you have you adding each order as a new record to your table, so when you have 5 orders with one users your table will look like this.
user: Adiiia | order: 5
user: Adiiia | order: 3
user: Adiiia | order: 7
user: Adiiia | order: 2
user: Adiiia | order: 9
when you query the database you are saying to mysql: get me the maximum number of the record i have with user: Adiiia. The result should be 9
If you want to count the sum of the records you should use sum
select sum(ord) from article where user_id='".$_SESSION['userId']."'
The result should be 26
The best thing you can do is by creating a new table orders_sum
The structure should like like this.
Total_orders | User
when a user have a new order you can update the table by adding one or else if have a order removed then removing minus one order.
Something like this.
Total_orders | User
5 | Adiiia
When you want to update:
select Total_orders from orders_sum where User='Adiiia'
Find how many orders the user have by fetching the table.
$orders = $row['Total_orders'];
$plus_orders = $row['Total_orders'] + 1;
update orders_sum set Total_orders='".$plus_orders."' where user='Adiiia'
When you want to delete:
select Total_orders from orders_sum where User='Adiiia'
Find how many orders the user have by fetching the table.
$orders = $row['Total_orders'];
$minus_orders = $row['Total_orders'] - 1;
update orders_sum set Total_orders='".$minus_orders."' where user='Adiiia'
Lets say article table having primary key article_id then after delete any article for user_id. Fetch all the article_id for the user_id. Then update the order for all the article_id for that user.
$queryArticle = mysql_query("select article_id from article where user_id=" .$_SESSION['userId']." order by article_id asc");
$allArticle = [];
while($rowArticle = mysql_fetch_assoc($queryArticle)){
$allArticle[] = $rowArticle['article_id'];
}
$query = "UPDATE article SET ord = (CASE order ";
foreach($allArticle as $order => $article_id) {
$query .= " WHEN {$article_id} THEN {$order}";
}
$query .= " END CASE) WHERE article_id IN (" . implode(",", $allArticle) . ")";
Related
I have a Part Management system I've created in PHP with MySQL. What I'm trying to create is something that will generate the next Part Number for me. All part numbers start with a 3 letter prefix (which is determined by the product family/category) followed by their number.
For example 'ABC001'
What I have below is something that I'd like to use to determine what the next number is having already 'ABC001', 'ABC002' & 'ABC003' so I would like it to recognize what the next number is by querying until the query comes back false because that product number doesn't exist yet.
$abc_query = "SELECT * FROM products WHERE id LIKE 'ABC%'";
$abc_result = $mysqli2->query($abc_query);
while($row = $abc_result->fetch_assoc()) {
$rowid = $row["id"];
$pnumber = substr($rowid, 3, 3);
echo $pnumber. '<br/>';
$int = (int)$pnumber;
$abc_query2 = "SELECT * FROM products WHERE id 'ABC" . sprintf('%03s', $int);
for ($abc_query2 = true; $abc_query2 = false; $int++){
echo $int;
}$abc_nextnumber = $int +1;
}
$abc_newnumber = 'ABC' . sprintf('%03s', $abc_nextnumber);
echo $abc_newnumber;
The result I get is
001
002
003
005
ABC006
However the result should be..
001
002
003
ABC004
code update I've updated the code but it doesn't seem to stop at ABC004 if I have an 005. It will go to 006.
You should have the db do this instead of your app:
select t.id_prfx, max(t.id_num) as latest_num from
(select substring(id, 1, 3) as id_prfx,
cast(substring(id,4) as integer) as id_num) t
group by id_prfx
This will give you a result table where you get the highest part number for each prefix.
If you really really only want prefixes of 'ABC' then:
select max(cast(substring(id,4) as integer)) as max_num from table
where id LIKE 'ABC%'
Could you try this query?
SELECT MAX(SUBSTR(id, 4)) as last_id FROM products WHERE SUBSTR(id, 1, 3)='ABC'
EDİT:
products TABLE
==============
ABC001
ABC002
ABC003
ABC005
==============
We want to find 4 in products table.
SELECT SUBSTR(t1.id, 4) + 1 as POSSIBLE_MIN_ID
FROM products t1
WHERE NOT EXISTS (
SELECT *
FROM products t2
WHERE SUBSTR(id, 1, 3)='ABC' AND SUBSTR(t2.id, 4) = SUBSTR(t1.id, 4) + 1
) LIMIT 1
RESULT:
POSSIBLE_MIN_ID : 4
If anyone knows how I can have it add automatic zeros to the into the query (as it will be different amount of 0s once it gets to 'ABC011') instead of typing them in that would also be very helpful.
Here's how to automatically handle the prepended zeroes.
$sql3 = "SELECT * FROM products WHERE id 'ABC" . sprintf('%03s', $int);
I have a table code with the following table structure. id is auto incrementing id, the code is a random unique 15 digit code and customer_id is the customer's id.
id code customer_id
1 123...4 1
2 124...5 1
3 128...3 1
4 234...1 2
5 678...3 2
6 567...8 1
The code is actually a 15 digit number which I am generating randomly as per below code. Based on the user input for the number of codes I generate the codes at once, insert ignore into the table and count post addition to the table if few lines were ignored due to duplicates and add the additional ones needed to make the total count needed by the user. I use this approach because the request for the number of codes is usually around 50k to 100k and this approach works well.
do{
$codes = array();
$question_marks = array();
$sql = "SELECT count(*) FROM code";
$stmt = $this->db->prepare($sql);
$stmt->execute();
$initialCount = $stmt->fetchColumn();
for ($i=0;$i<$codesToGenerate;$i++){
$code = getToken(15);
array_push($codesArray, $code, $customerId);
$question_marks[] = '(' . placeholders('?', 2) . ')';
}
$datafields = "code, customer_id";
$this->db->beginTransaction(); // also helps speed up your inserts.
$sql = "INSERT IGNORE INTO code (" . $datafields . ") VALUES " . implode(',', $question_marks) ;
$stmt = $this->db->prepare($sql);
try {
$stmt->execute($codesArray);
}catch (\PDOException $e){
echo $e->getMessage();
$result = 0;
}
$this->db->commit();
$sql = "SELECT count(*) FROM code";
$stmt = $this->db->prepare($sql);
$stmt->execute();
$finalCount = $stmt->fetchColumn();
$rowsInserted = $finalCount - $initialCount;
$codesGenerated += $rowsInserted;
$codesToGenerate = $codesToGenerate - $rowsInserted;
}while($codesToGenerate>0);
I have added a column serial_number in table and I want to add a serial_number which will increment for each value of respective customer like below based on the customer_id. How do I change PHP code to add serial_number as well. Please note that I want to avoid holes in serial_number.
id code customer_id serial_number
1 123...4 1 1
2 124...5 1 2
3 128...3 1 3
4 234...1 2 1
5 678...3 2 2
6 567...8 1 4
How do I do this?
Below are some of my thoughts:
1)Should it be done seperately post this transaction?
2)Should I maintain a last count of serial_number for each customer in a separate table and then increment in PHP before adding to table.
3) How do I take care of concurrencies if I use the approach mentioned in 2 above
need a help with a PHP/MySQL issue. I have a table named bids and two column named buyer and tagged both using int.
buyer
--------------
8
5
2
tagged
--------------
5
4
1
I'm trying to detect multiple same entry number. I want if a same number appears on both of the column it shouldnt display on the menu list anymore, hope yo understand.
Any tip?
code below
$query = "SELECT b.auction, b.buyer, b.bid, b.bidwhen, b.quantity, b.willwin, b.tagged, b.balance, u.nick, u.rate_sum FROM " . $DBPrefix . "bids b
LEFT JOIN " . $DBPrefix . "users u ON (u.id = b.bidder) WHERE b.auction = :auc_id
ORDER BY b.bid asc, b.quantity DESC, b.willwin asc"; $params = array(); $params[] = array(':auc_id', $id, 'int');
well, I have 2 Mysql table which structure is bellow :
Table Jobs
job_id---job_cat_id---job_title---job_description---job_data----is_active
=========================================================================
1 1 title 1 description 1 2016-05-06 1
2 2 title 2 description 2 2016-05-06 0
3 2 title 3 description 3 2016-05-06 1
Table job_details
job_cat_id---job_cat_name
=========================
1 cat name 1
2 cat name 2
3 cat name 3
Now I want to show all jobs under each category from jobs table. E.g
What I need to show :
Job Category 1
1. job 1 from category 1
2. Job 2 from category 1
Job Category 2
1. Job 3 from category 2
So to do this I am using following sql query but can't get the correct result :
$get_job = mysqli_query($conn, "SELECT jobs.job_id, jobs.job_title, job_category.job_cat_name FROM jobs LEFT JOIN job_category ON job_category.job_cat_id = jobs.job_cat_id WHERE jobs.is_active = '1' ");
while($result = mysqli_fetch_array($get_job) ) {
$job_id = (int) $result['job_id'];
$job_title = htmlspecialchars($result['job_title']);
$job_category = htmlspecialchars($result['job_cat_name']);
echo "<h4>$job_category</h4>";
echo "<p>$job_title</p>";
}
Now, It's showing me all category with all jobs but I want to show all jobs under each category.
What is showing now :
Job Category 1
1. job 1 from category 1
Job Category 1
1. Job 2 from category 1
Job Category 2
1. Job 3 from category 2
First we have to remember that the result from a SELECT query is a newly generated table. It is not a multi dimensional array. If it were a multidimensional array, then you could get away with printing the job category at the beginning of each new array which could be grouping up all the jobs in a single category, however since this is not the type of result obtained by the SQL SELECT QUERY, you are printing the job category after each line:
echo "<h4>$job_category</h4>";
echo "<p>$job_title</p>";
Solution:
A solution to your problem would be to first use the ORBER BY ASC in your sql query:
$get_job = mysqli_query($conn, "SELECT jobs.job_id, jobs.job_title, job_category.job_cat_name FROM jobs LEFT JOIN job_category ON job_category.job_cat_id = jobs.job_cat_id WHERE jobs.is_active = '1' ORDER BY job_cat_id ASC");
From there, you know that the jobs in each category should at least be grouped up next to each other (from lowest to highest like 1,1,1,1,2,2,3,3,3). What you can now do is have a conditional print the $job_category if AND ONLY IF it hasn't been printed already previously.
Change this line:
echo "<h4>$job_category</h4>";
into this line:
if ($previous_print != $job_category)
{
echo "<h4>$job_category</h4>";
$previous_print = $job_category;
}
Let me know if it works now.
Another solution may be if you just run one query using group by job_cat_id and then inside loop write another query to get desired result with where clause job_cat_id .
You need to do 2 queries here. Here's an exmaple code, might need some tweaks acording to your table column names:
<?php
$query = "SELECT `job_cat_id`, `job_cat_name`, COUNT(`jobs`.`id`) as `jobs`
FROM `job_category`
GROUP BY `job_cat_id`";
$get_cat = mysqli_query($conn, $query);
$cats = [];
while($result = mysqli_fetch_array($get_cat) ) {
$result['jobs'] = [];
$cats[$result['job_cat_id']] = $result;
}
$get_job = mysqli_query($conn, "SELECT jobs.job_id, jobs.job_title, jobs.job_cat_id FROM jobs WHERE jobs.is_active = '1' AND `job_cat_id` IN (" . implode(',', array_keys($cats)) . ")");
while($result = mysqli_fetch_array($get_job) ) {
$cats[$result['job_cat_id']][] = $result;
}
foreach ($cats as $cat) {
$job_category = htmlspecialchars($cat['job_cat_name']);
echo "<h4>$job_category</h4>";
foreach ($cat['jobs'] as $job) {
$job_title = htmlspecialchars($job['job_title']);
echo "<p>$job_title</p>";
}
}
I have a mysql table consisting of users following other users.
USER_ID FOLLOW_ID
1 2
1 3
2 4
3 4
6 4
2 6
I am user No. 2 and the person in question is user No. 4. You see that three people are following user No.4 including me. I can query the users who are following user No.4. How can I add to the query if I am following these people or not? So what I would like to know is who are following a specific user (No.4 in this case) and which one of them I am following.
Desired result:
USER_ID (No.4 is FOLLOWED BY), DO_I_FOLLOW_HIM
2 No
3 No
6 Yes
As you see from the last record of the table I (No.2) am following User No.6.
Query the list of people following user No.4:
$myid = '6';
$userid = '4';
$i = 0;
try {
$stmt = $conn->prepare("SELECT USER_ID FROM FOLLOW WHERE FOLLOW_ID=?");
$stmt -> execute(array($userid));
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$row2[$i] = $row['USER_ID'];
$i++;
}
} catch(PDOException $e) {
echo 'ERROR: ' . $e->getMessage();
$response["success"] = 0;
}
Sample SQL Fiddle for help: http://sqlfiddle.com/#!2/97ac6
SELECT him.user_id, IF(i.follow_id,'yes','no') AS i_follow_him
FROM Follows him
LEFT JOIN Follows i ON (i.follow_id = him.user_id AND i.user_id = 2)
WHERE him.follow_id = 4
To get a list of users that you follow that are following another given user, you need to use a subquery. You can see it when written above you are asking two things
Who is following person A
From that list who am I following.
So You could try using a query like so,
Select User_ID, Follows_ID
From Follows
Where User_ID = ?
And Follow_ID In (Select User_ID From Follows Where Follow_ID = ?)
To see a list and whether you're following
Select f.User_ID,
Case When ? In (Select User_ID From Follows Where Follow_ID = f.User_ID) Then 'Yes' Else 'No' End
From Follows f
Where f.Follow_ID = ?
#Shudder makes a good point, you may see performance increases (especially if this is a large table) by using a join instead of a subquery.
SELECT him.user_id, IF(i.follow_id,'yes','no') AS i_follow_him
FROM Follows him
LEFT JOIN Follows i ON (i.follow_id = him.user_id AND i.user_id = ?)
WHERE him.follow_id = ?
I made it easier by adding your own id and user No 4.
select follow_id
from follows
where user_id=2 and follow_id IN (select user_id from follows where follow_id=4)