I have a basic SQL problem that's been driving me mad. If I have a mySQL table e.g below.
How would I add another 80+ values to Column 2 starting from the first empty row (in this example row 3).
I've been trying a number of queries using INSERT or UPDATE but the closest I've got is to add the values to column 2 starting from the last defined ID value (e.g. row 80ish).
ID | Column 2 |
--------------------------------
1 | value |
2 | value |
3 | |
4 | |
5 | |
etc
The real table has around 10 columns, all with data in but I just need to add content (a list of around 80 different strings in CSV format to one of the columns)
I'd appreciate it if anyone could point me in the right direction.
I'd load the data into a separate table with the same structure and then update the target table using join or subquery to determine which columns are currently empty.
i.e. load interim table and then:
update target_table set column2 = (select column2 from interim_table where ...
where column2 is null
(slow but intuitive)
update target table, interim_table
set target table.column2 = interim_table.column2
where target table... = interim_table...
and target_table.column2 is null
(better performance)
Why don't you first run a query to find out the first empty row ID number? you can use SELECT COUNT(*)
FROM TABLE_NAME for that.
then you create a for loop and inside run a INSERT query, starting with the value returned by the previous query. just a scratch:
for(var id = last; id < totalOfQueries; id++)
{
var query = new MysqlCommand("INSERT INTO table VALUES ('" + id + "',....);
}
Related
let me say that I have a table in my phpmyadmin that looks like this:
id | name
1 | John
2 | Dave
5 | Tiffany
As U can see by id - i've deleted 2 records between 'Dave' and 'Tiffany'.
My question:
Is there a way to 'reset' or repopulate the id so that the 'Tiffany' record would have id=3 and so on ?
The only way to start counting id again I've found is a 'TRUNCATE' but it deletes all my records which I dont want
I do this sometimes when I create a new table and want to get 'clean' ids. If there is no reference to / connection with other table, you can do:
SET #var:=0;
UPDATE `table` SET `id`=(#var:=#var+1);
ALTER TABLE `table` AUTO_INCREMENT = 1;
Do not do this for ids already used in other tables!
I have a table in this format:
id | ....... | other_id
-------------------------
1 | ....... | 5
2 | ....... | 2
Basically, when the form is submitted, sometimes there will be a value for other_id in the form, and the insertion of the new row goes as normal. However, if there is no value given for other_id, I want its value to come from id. The issue is that id is the auto incrementing id, so the actual value of id is unknown until it's actually inserted into the table.
Is there a way to dynamically do this with SQL itself, without having to run additional queries afterward?
You can use a insertion trigger:
CREATE TRIGGER foo AFTER INSERT ON TABLENAME FOR EACH ROW
IF NEW.other_id IS NULL THEN
SET NEW.other_id := NEW.id;
END IF;;
#jh314 is almost right. Just change AFTER INSERT to BEFORE INSERT
How can I SELECT the last row in a MySQL table?
I'm INSERTING data and I need to retrieve a column value from the previous row.
(I'm using PHP by the way.)
the table1 something like this
table1
******************
cate_id | task_id | start_date | end_date | line |
1 2 30/04/2012 26/06/2012 text
3 1 26/06/2012 27/06/2012 text
2 1 27/06/2012 01/01/9999 text
There'sNO an auto_incrementin that table.
And my case is to update the existing last row in table and then insert a new one.
You've edited question so, here's update
SELECT MAX(cate_id) AS last_cate_id FROM table;
or you can get next ID by:
SELECT MAX(cate_id)+1 AS next_cate_id FROM table;
Without transactions this is very vulnerable for inserting same cate_id!
If you cant use them, for example because of MyISAM, you could insert with select.
INSERT INTO table
(cate_id, task_id ..)
VALUES
( (SELECT MAX(cate_id)+1 AS next_cate_id FROM table), 1 )
if you don't have order by you wont be able to get the "LAST" value or the first, because the order will not be the same (necessarily), if you don't have auto increment how can you know which one is the first or the last?, if you are working with date or auto increment you will be able to get that, however, lets say that you have a order by 'column1' you can do something like:
select * from table1 order by `column1` desc limit 1
I think most people had serious problems with inserting a value/data into a database (mysql). When I'm inserting a value into a database, I assign an unique id (INT) for that line. When I query the database, easily I can read/modify/delete that line.
With function for() (in php) I easily can read values/data from the database. The problem occurs when I delete a line (in the middle for example).
E.g:
DB:
ID | column1 | column2 | ... | columnN
--------------------------------------
1 | abcdefgh | asdasda | ... | asdasdN
2 | asdasddd | asdasda | ... | asdasdN
...
N | asdewfew | asddsad | ... | asddsaN
php:
for($i = 0; $i <= $n; $i++){
$sql = mysql_query("SELECT * FROM db WHERE ID = '$i' ");
//Code;
}
*$n = last column value from ID
Am I need to reorganize the entire database to have a correct "flow" (1, 2, 3, .. n)? Or am I need to UPDATE the each cell?
What you're doing here is unnecessary thanks to AUTO_INCREMENT in mysql. Run this command from PhpMyAdmin (or another DB management system):
ALTER TABLE db MODIFY COLUMN ID INT NOT NULL AUTO_INCREMENT;
Now when insert a row into db mysql will assign the ID for you:
INSERT INTO db (id, column1, column2) VALUES(NULL, 'abc', 'def');
SELECT * FROM db;:
+--+-------+-------+
|id|column1|column2|
+--+-------+-------+
|1 |old |oldrow |
+--+-------+-------+
|2 |abc |def | <--- Your newly inserted row, with unique ID
+--+-------+-------+
If you delete a row, it is true that there will be an inconsistency in the order of the ID's, but this is ok. IDs are not intended to denote the numeric position of a row in a table. They are intended to uniquely identify each row so that you can perform actions on it and reference it from other tables with foreign keys.
Also if you need to grab a group of ID's (stored in an array, for example), it is much more efficient to perform one query with an IN statement.
$ids = array(1,2,3,4,5,6);
$in = implode(',', $ids);
mysql_query('SELECT * FROM db WHERE id IN ('.$in.')');
However, if you want all rows just use:
SELECT * FROM dbs;
But be weary of bobby tables.
You can select all the rows with query
SELECT * FROM db
and do whatever you want after
You can never ensure, that the ids are continous. As you noticed yourself there are gaps after you delete a row, but even for example when you insert rows within a transaction and don't commit it, because something failed and you need to revert the transaction. An ID is an identifier and not row number.
For example if you want to select X items from somewhere (or such) have a look at LIMIT and OFFSET
SELECT * FROM mytable ORDER BY created DESC LIMIT 10 OFFSET 20;
This selects the rows 21 to 30 ordered by their creation time. Note, that I don't use id for ordering, but you cannot rely on it (as mentioned).
If you really want to fetch rows by their ID you definitely need to fetch the IDs first. You may also fetch a range of IDs like
SELECT * FROM mytable WHERE id IN (1,2,3,4);
But don't assume, that you will ever receive 4 rows.
Ids are surrogate keys–they are in no way derived from the data in the rest of the columns and their only significance is each row has a unique one. There's no need to change them.
If you need a specific range of rows from the table, use BETWEEN to specify them in the query:
SELECT id, col1, col2, ..., coln
FROM `table`
WHERE id BETWEEN ? AND ?
ORDER BY id
If you need all the rows and all columns for that table use:
$query = mysql_query("SELECT * FROM table_name");
and then loop through each row with a while statement:
while ($row = mysql_fetch_array($query ))
{
echo $row['column_name'];
}
You do not have to reorganize the entire database in order to keep the index. But if you feel like it, you'd have to update each cell.
BTW, look at mysql_fetch_array(), it will ease the load on the SQL server.
I have a MySQL query that looks like this:
UPDATE `Table` SET `Column` =
CASE
WHEN `Option Id` = '1' THEN 'Apple'
WHEN `Option Id` = '2' THEN 'Banana'
WHEN `Option Id` = '3' THEN 'Q-Tip'
END
An my table currently looks like this:
Option Id | Column
1 | x
2 | x
I'd like it to result in:
Option Id | Column
1 | Apple
2 | Banana
3 | Q-Tip
But it doesn't insert the Q-Tip row. I've looked up and read a bit about INSERT ON DUPLICATE KEY UPDATE and REPLACE, but I can't find a way to get those to work with this multiple row update using CASE. Do I have to write a separate query for each row to get this to work, or is there a nice way to do this in MySQL?
Option Id is not a Key itself, but it is part of the Primary Key.
EDIT Some more info:
I'm programming in PHP, and essentially I'm storing an array for the user. Option Id is the key, and Column is the value. So for simplicities sake, my table could look like:
User Id | Option Id | Value
10 | 1 | Apple
10 | 2 | Shoe
11 | 1 | Czar
...
That user can easily update the elements in the array and add new ones, then POST the array to the server, in which case I'd like to store it in the table. My query above updates any array elements that they've edited, but it doesn't insert the new ones. I'm wondering if there is a query that can take my array from POST and insert it into the table without me having to write a loop and have a query for every array element.
This should work, if Option_Id is a primary key:
REPLACE INTO `Table` (`Option_Id`, `Column`) VALUES
(1, 'Apple'),
(2, 'Banana'),
(3, 'Q-Tip');
The statement means: Insert the given rows or replace the values, if the PK is already existing.
Of course it does not insert. As there is no such value, it cannot get updated.
I suppose you are normalizing a database by putting in the values already present and now want to add the required mapping for every valid value.
So it would be better to start from scratch and just do INSERTs.
You could always query the database for entries and then choose update or insert based on yor results
I see no point in such updating.
Why don't you have a separate table with option ids and corresponding values, leaving only option ids linked to user ids in this one?