I got a set of queries that will be interupted. Therefore I need to stop the query, save the last added ID and continue adding contents from the last ID on another day.
Szenario:
1) I query data from another table (Table-A) like this:
SELECT *
FROM $table_A
ORDER BY uID ASC
2) Then I add to a table (Table-B) that "looks" like this:
|¯¯¯¯¯|¯¯¯¯¯¯¯¯|¯¯¯¯¯¯|¯¯¯¯¯|¯¯¯¯¯|
| uID | SubID* | Name | Foo | Bar |
|-----|--------|------|-----|-----|
| 1 | 23 | Boo | Goo | Shu |
|_____|________|______|_____|_____|
3) For each row I query from the Table-A table I add data to the Table-B table. (Note: This table already has the uID, SubID and Name when I add the data.)
4) The query gets interrupted/stops. Then I save the uID* of the latest added row - before the queries stop - to a separate table (Table-C).
Question: How can I start the query - after interruption (let's say on the next day) - again, but starting from the next row after last I saved on the previous day (The uID will be available).
Example:
SELECT *
FROM $table_A
ORDER BY uID ASC
LIMIT $last_uID, COUNT $table_A (a.k.a "the last ID in the table")
Thanks!
Notes:
The SubID connect rows to other tables & can exist more than once.
UID = Unique Identifier (Auto Increment).
Well you know what the last ID added was, because it will be in table_B.
SELECT *
FROM $table_A
WHERE uID > (select max(uID) from table_B)
ORDER BY uID ASC
UPDATE:
Seems this is what is required.
SELECT all columns
FROM $table_A
WHERE uID BETWEEN $last_uID_added AND $last_uID_in_table;
Related
I would like to create a queue system that works in this way:
A user fills in a form where they will have to enter some data.
Click on Send and these data will be saved in a sql table.
Going to the index.php page will see a box containing a text like this: There are 4 requests in front of you, please wait a few minutes.
I have already tried to do such a thing, but going to create new requests the number "4" of the message grows.
This is because I created a query that counts all the results on the table.
$query = $mysql->query("SELECT COUNT(*) AS q FROM application_approve");
While I want it to count only the results above the request that sent the user.
id name text text2
1 First request dassasad dsadasas
2 Second request dassasad dsadasas
3 Third request dsadasdsas dsadasad
In the example above I would like to count only how many lines there are above the "Second Request": in this case 1.
Assuming your table has a PK (id) and references a user_id to identify which request belongs to which user and assuming there can only be a single request in the queue per user then your query would look something like the following.
SELECT COUNT(id) AS q FROM application_approve
WHERE id < (
SELECT id FROM application_approve
WHERE user_id = ?
)
This also assumes the PK id is an auto-incrementing key.
Given the user_id this query would return the number of rows above the given user's row (assuming they have one). Or, in other words, all ids less than the id of the given user.
For simplicity, let's assume this schema only has 2 columns (id and user_id):
mysql> SELECT * FROM application_approve;
+------+---------+
| id | user_id |
+------+---------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
+------+---------+
3 rows in set (0.00 sec)
So in the given table, there are 3 users, each with 1 entry in the queue.
If we wanted to find which position user 2 is in the query would give us the following result:
mysql> SELECT COUNT(id) AS q FROM application_approve WHERE id < (SELECT id FROM application_approve WHERE user_id = 2);
+---+
| q |
+---+
| 1 |
+---+
1 row in set (0.00 sec)
My table looks like this:
+------------------------+
| id | title | position |
+------------------------+
| 1 | test 2 | 3 |
+------------------------+
| 2 | test 3 | 1 |
+------------------------+
| 3 | test 1 | 0 |
+------------------------+
I found this query which retrieves the rows ordered based on the position field which holds the id of the predecessor.
SELECT
*
FROM
mytable AS t1
LEFT JOIN
mytable AS t2
ON t2.position = t1.id
I wonder why this is working because there is no order by clause and the database should't know that position 0 is the row to start at.
The result is dependent on the order you inserted the rows into the table. If, for example, you had inserted the row with id=3 before you inserted the row with id=2, then you would have got a non-sorted result.
As it stands, you are pulling the data out of t1 in the order of id because that is the order you put the elements into the table
See http://sqlfiddle.com/#!2/63a925/2 and try it for yourself.
N.B. Databases are not guaranteed to work as you state, it is simply that most databases work this way. You should not rely on this behaviour as a minor change to the schema or query could ruin your whole day! Note also that if id is a (primary?) key, the insert order will probably be overridden by the fact that the database will pull the rows out in the order of the index.
That query is joining in table 2 based on the ID in table 1 equaling the position in table 2. Since the IDs in table 1 are sequential, the output appears to be sorted
I have the following table:
AMAZON_ID | DATE | STATUS
1 | 01/03/2014 | Pending
1 | 01/03/2014 | Shipped
2 | 01/04/2014 | Pending
3 | 01/05/2014 | Cancelled
4 | 01/06/2014 | Pending
How can I select the earliest date from table where status is equals Pending where the count of id is not more then one, it should be like the following:
AMAZON_ID | DATE | STATUS
2 | 01/04/2014 | Pending
I can not figure that out, this is what I have so far but its not working:
SELECT date
FROM table
WHERE status = 'Pending'
AND COUNT(id) < 2
ORDER BY date ASC
LIMIT 1;
Use a subquery to GROUP BY the id's that have COUNT of 1. Make sure your id is IN the results of this subquery, with a status of pending. Then ORDER BY date and LIMIT to the first result.
SELECT date
FROM table
WHERE
status = 'Pending' AND
id IN (
SELECT id
FROM table
GROUP BY id
HAVING COUNT(*) = 1
)
ORDER BY date ASC
LIMIT 1;
One thing you can do is use a WHERE IN, and use a select statement to populate the WHERE clause with distinct ids
SELECT date
FROM table
WHERE status = 'Pending'
AND id IN (SELECT DISTINCT id FROM table)
ORDER BY date ASC
LIMIT 1;
It depends on what you really mean by "count of id is not more than one".
I have renamed your column date to ts to make the queries valid SQL (as DATE is a SQL function so it may confuse parsers). See the SQL fiddle for the complete schema I used and the example queries.
Option 2: one row per ID total
In this case you have a problem because you want a query to get one piece of information (the minimum date) that is based on a different piece of information about the same table. This means that you need to queries, luckily you can just join the data of the two queries and filter appropriately.
SELECT data.id, status, MIN(ts)
FROM data
JOIN (SELECT id, COUNT(*) AS amount FROM data GROUP BY id) AS totals
ON totals.id = data.id
WHERE
status = "Pending"
AND totals.amount < 2
GROUP BY data.status;
Option 1 (easy): only one pending row per ID
NOTE: this answer does not answer the OP's question
In this case, the situation is quite easy as you can just filter all your rows with status "pending", the minimum date and the total amount of rows that match your result and, after the aggregation (i.e.: using HAVING) filter those that have less than 2 amounts.
In SQL that would be:
SELECT id, status, MIN(ts) AS minTS, COUNT(*) AS amount
FROM data
WHERE
status = "Pending"
GROUP BY id, status
HAVING amount < 2
I've got two tables which are related to each other. I want to change table 1 status to updated when I insert new values into table 2 and return mysqli_affected_rows() for table 1
table 1: products
id | name
1 | product
table 1: categories
id | name | product_id
1 | cat 1 | 1
2 | cat 2 | 1
is this possible?!
You show the structure of the tables, but don't include any column that should be updated. This makes me think that you don't really want an update. You just want a query that returns whether a given product is in the categories table.
If so, the following may do what you want:
select p.*,
coalesce( (select 1 from categories c where c.productid = p.id limit 1), 0) as InCategories
from products p;
If you try to go another route where you actually store the value in the table, you will need to use a stored procedure or triggers. Do consider, though, what happens when you delete or update a row. insert is not the only way to modify data in a table.
I have a table that I use to keep track of some associations between users and various other aspects of their website.
I need to be able to get the first available row and update one or two of it's columns ... the criteria is whether or not the user_id column has been used or not.
id | tag_id | user_id | product_id
If a row has a tag available where there is no user_id assigned, I want to be able to use and update that row for the latest purchased product.
1 | 100001 | 29 | 66
2 | 100002 | 0 | 0
3 | 100003 | 0 | 0
So as you can see, the second row would be the first eligible candidate.
I'm just not sure what the SQL needs to be in order to make that happen
UPDATE yourTablename SET user_id = 'your value for userid',
product_id='ur value for productid' WHERE id=(select min(id) where user_id='0');
alternative method already told are efficient but if your table has sorting with id
UPDATE yourTablename SET user_id = 'your value for userid',
product_id='ur value for productid' where user_id='0' LIMIT 1;
If I understand you correctly you want to update the first available empty (not NULL but empty) user_id row. How's this?
UPDATE users
SET user_id = 'user_value_here'
WHERE user_id=''
LIMIT 1
If your index is sorted ASC, the query below should find the first result in order.
See the fiddle.
UPDATE table SET user_id = 1 WHERE user_id IS NULL LIMIT 1
You can replace IS NULL with the condition for an empty user_id.