I have to update a mysql table using PHP's mysql_query() function. Therefore I need to send the following UPDATE query in only one statement:
SET #i = 0;
UPDATE mytable SET id=(#i:=#i+1);
I have read some examples where this can be done with SELECT statements using table aliases like:
SELECT #rn:=#rn+1 AS rank, t1.* FROM (SELECT * FROM mytable) t1, (SELECT #rn:=0) t2
Is there some way to use these table aliases with the UPDATE statement that I need to use?
Edit:
Based on Topher Hunt's answer, I think I could create a copy of mytable using:
CREATE TABLE mytable_copy SELECT #rn:=#rn+1 AS id, t1.* FROM (SELECT * FROM mytable) t1, (SELECT #rn:=0) t2
Then DROP mytable and RENAME mytable_copy to mytable.
Would this statement create an exact copy of mytable, with the same field types and lenghts that the ones in mytable?
If you use JOINs between your tables, the syntax is very similar between SELECT and UPDATE statements. Example:
SELECT *
FROM table1 a
JOIN table2 b ON a.something = b.something ## (conditions for linking tables)
JOIN table3 c ON b.something = c.something
WHERE a.something = 'value'
A SELECT statement that joins 3 tables, can be turned around into an UPDATE statement just by removing the SELECT line, changing the word FROM to UPDATE, and adding a "SET" clause to say what you want to change. Like this:
UPDATE table1 a
JOIN table2 b ON a.something = b.something ## (conditions for linking tables)
JOIN table3 c ON b.something = c.something
SET a.variable = 'value2',
b.something = 'value3',
c.somethingelse = 'value4'
WHERE a.something = 'value';
You can make changes to lots of fields at the same time, if needed; just separate each SET item with commas.
Why not just drop this column and add a new column as a primary key with auto_increment? This will automatically assign the values you require.
ALTER TABLE mytable DROP COLUMN id;
ALTER TABLE mytable ADD ( id int AUTO_INCREMENT PRIMARY KEY );
-or- as you requested...
UPDATE mytable
JOIN (SELECT #xxx := 0) AS v1
SET id = (#xxx := #xxx + 1)
;
Related
First post, be gentle! My SQL knowledge is average, at best.
I have 2 tables with no direct relationship to each other.
TableA ("CustomerWishList") with columns "bookID", other-book-data,
etc etc etc
TableB ("CustomerOwned") with columns - "bookID", other-book-data, etc etc etc
A book could be in one, both, or none of those tables.
I need to create SQL statement that counts the number of "bookID='data'" occurrences in either TableA or TableB.
So far using PHP I'm searching TableA "bookID" column first, and then if nothing found, searching TableB "bookID" column next ... it works, but is inefficient, and am convinced there must be a better way.
JOIN statements don't seem to apply here? - I could be wrong.
UPDATED
Psuedo PHP code I'm currently using:
$total=SELECT COUNT(*) FROM CustomerWishList WHERE BOOKID=1234
if ($total==0) {
$total2=SELECT COUNT(*) FROM CustomerOwned WHERE BOOKID=1234
}
return $total2;
Below query would give you count of book ids which are only in table A:
SELECT count(1) as `count`
FROM tableA
WHERE NOT EXISTS
(SELECT bookID FROM tableB WHERE bookID = tableA.bookID);
Similarly, following query would give you count of book ids which are only in table B:
SELECT count(1) as `count`
FROM tableB
WHERE NOT EXISTS
(SELECT bookID FROM tableA WHERE bookID = tableB.bookID);
Now, if you want to add these two then you can use the following query:
SELECT `a.count` + `b.count`
FROM (
SELECT count(1) as `count`
FROM tableA
WHERE NOT EXISTS
(SELECT bookID FROM tableB WHERE bookID = tableA.bookID)
) a,
(
SELECT count(1) as `count`
FROM tableB
WHERE NOT EXISTS
(SELECT bookID FROM tableA WHERE bookID = tableB.bookID);
) b;
I have two tables table1 and table2
In table1 fieldname is cert_no and in table2 fieldname is cer1,cert2,cert3,cert4,cert5
The value which was not in table2 (cer1,cert2,cert3,cert4,cert5) alone want to display
If both table has same value only transfile_file want to display
SELECT *
FROM table1
WHERE folio = '123456'
AND cm_flag !='X'
AND certificate_no NOT IN
(SELECT CONCAT(certno1,certno2,certno3,certno4,certno5,certno6,certno7,certno8,certno9,certno10)
FROM table2
WHERE tofolio = '123456'
)
If you use for example Microsoft SQL Server there is a function EXCEPT that return the different rows between 2 tables with the same fileds (same name, same types and same positions). In Oracle there is MINUS operation that is the same of EXCEPT.
In MySQL does not implement a EXCEPT or MINUS operation which is a unfortunate as it can allow for better execution plans in some cases than the alternatives.
This is a valid aternative and more performing than use NOT IN operation: realize a join is the best solution in SQL.
enter code here
SELECT a.*
FROM table1 as a
LEFT JOIN table2 as b
ON a.tofolio = b.tofolio
WHERE b.tofolio IS NULL
Try:
SELECT * FROM table1 WHERE folio = '123456' AND cm_flag !='X' AND certificate_no NOT IN (SELECT CONCAT(certno1,',',certno2,',',certno3,',',certno4,',',certno5,',',certno6,',',certno7,',',certno8,',',certno9,',',certno10) FROM table2 WHERE tofolio = '123456')
I have the below table (in picture) which is kind of inventory table and shows how many items comes in and how many goes out from stock, and item_id is the foreign key from another table.
I want to select those records that has no out from the stock, in other word i want to select those records which are highlighted in green (in the picture).
Thanks.
Sorry for poor English
The Table
Try this:
Select * from `table` where id in (select id from `table`group by id having sum(out)=0);
for deleting those values use:
delete t1
from `your_table` as t1
join (select item_id from `your_table`group by item_id having sum(item_out)=0) t2 on t1.item_id = t2.item_id
Try this query.
SELECT * FROM 'table_name' where out=0;
You need to join the table to itself: SELECT t.* FROM <your_table> AS t LEFT JOIN <your_table> AS t1 ON t.item_id=t1.item_id WHERE t1.out>0 AND t1.item_id IS NULL
I am using PHP and MySQL and I have 2 tables containing the fields number and name. The name field in table1 is empty by default and where there is a row in table2 with a matching number I would like to update the name in table1.
The following pseudocode illustrates this:
select number, number
from table1, table2
if number from table1 == number from table2
then insert or update name from table1 with the value of name from table2
In MySQL you could do
UPDATE table1 t1
INNER JOIN table2 t2 ON t1.number = t2.number
SET t1.name = t2.name
A more ANSI answer where you can't rely on joining in an update statement would rely on sub-queries, e.g.:
UPDATE table1 t1
SET name = (SELECT name FROM table2 t2 WHERE t2.number = t1.number)
WHERE EXISTS (SELECT 1 FROM table2 t2 WHERE t2.number = t1.number)
The WHERE ensures you are only updating the column where there is a matched row.
If I have a list of ID's that I have selected from a statement
SELECT id FROM myTable WHERE name = 'TEST'
This would return just the ids (1001, 1002, 1003, etc...) Then I want to perform another SELECT statement to retrieve all the titles for all those ids.
SELECT title FROM myTable2 WHERE id = XXXX
the id in table2 is the foreign key of table2. id in myTable is the Primary Key. How can I go about retrieving all the titles from those ids. I was thinking about storing all the results of the first select statement in an array, and then using a while loop to iterate through the list and return each result into another array, but my fear is that when the database gets big if it has to return 1000 rows that could be some bad overhead. So in PHP or SQL what is the best way to perform this?
You can use a subquery:
SELECT title
FROM myTable2
WHERE id IN (
SELECT id
FROM myTable
WHERE name = 'TEST'
)
Another way to do it would to be use a JOIN, to avoid the sub-query:
SELECT title
FROM myTable2
LEFT JOIN myTable
ON myTable.id = myTable2.id
WHERE myTable.name = 'TEST'
You should just be able to select them at the same time.
SELECT a.id, b.title
FROM myTable a, myTable2 b
WHERE a.name = 'TEST' AND b.id = a.id;
to select both:
SELECT id, title FROM mytable WHERE name="TEST"
or to select the whole row
SELECT * FROM mytable WHERE name="TEST"
if its two tables you are selecting from:
SELECT id, title FROM mytable A JOIN mytable2 B USING (id)