Update table increasing every row by 1 from max - mysql

I'm trying to increase several rows order field by one while taking into account max value of that field.
CREATE TABLE IF NOT EXISTS `jobs`(
`id` INT(11) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(128) NOT NULL,
`order` INT(11) NOT NULL DEFAULT 0,
PRIMARY KEY(`id`));
INSERT INTO `jobs`(`name`) VALUES("John"),("Steven"),("Marie"),("Clair"),("Richard"),("Rober"),("Barbara")
UPDATE
`jobs` AS `j1`,
(SELECT MAX(`order`) AS `max` FROM jobs) AS `j2`
SET `j1`.`order` = `j2`.`max` + 1
WHERE `j1`.`id` > 4
It sets rows of Richard, Rober and Barbara to 1 and I want to be 1,2,3 and if I would execute it again I want them to be 4,5,6
I know It would be perfect if the column order would be auto_increment / unique but it can't be in this case.

If you can use user defined variables then you can do so
UPDATE
`jobs` AS `j1`
cross join (
select #r:= (SELECT MAX(`order`) AS `max` FROM jobs)
) t
SET `j1`.`order` = #r:= #r + 1
WHERE `j1`.`id` > 4
Demo for single update
Demo for 2 times update

Related

How to sum all the value in a specific date in mysql

i want to sum all the values in a specific date in mysql but idk what is the right syntax
CREATE TABLE `trans` (
`id` int(12) NOT NULL,
`date_sold` datetime NOT NULL,
`total` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
ALTER TABLE `trans`
ADD PRIMARY KEY (`id`);
ALTER TABLE `trans`
MODIFY `id` int(12) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=8;
id
date_sold
total
1
2021-02-23
12
2
2021-02-23
6
3
2021-02-24
32
4
2021-02-24
10
now i want to sum all the values in that specific date
ex:
id
date
total
1
2021-02-23
18
2
2021-02-24
42
is that possible?
Alternative Use of ROW_NUMBER() function. Because ROW_NUMBER() isn't supported in below v5.8. First calculate date wise total and then apply id incrementally.
-- MySQL(5.6)
SELECT (#row_number:= #row_number + 1) id
, t.date_sold, t.total
FROM (SELECT date_sold
, SUM(total) total
FROM trans
GROUP BY date_sold ) t, (SELECT #row_number := 0) x
ORDER BY t.date_sold
Please check from URL https://dbfiddle.uk/?rdbms=mysql_5.6&fiddle=5cc2305b465ac2454be5bdb1a9e8af4a

mysql middle row deleted and fix primary key with arranging order

i have table with id that is primary key activated with 20 data inserted . and i have deleted row 15,16,17 and how can i arrange increasing order from 1 to 17
CREATE TABLE `cart` (
`id` int(255) NOT NULL,
`productname` varchar(255) NOT NULL,
`productquantity` varchar(255) NOT NULL,
`productsize` varchar(255) NOT NULL,
`productprice` varchar(255) NOT NULL
)
Determine row_number for each row, in an increasing order of id, starting from 1 in a Derived Table.
Join this Derived table with your main table, and update the id value to be equal to row_number. This will reset all the id values to start from 1 (with no gaps).
Try (works for all MySQL versions):
UPDATE your_table AS t1
JOIN
(
SELECT #row_no := #row_no + 1 AS row_num,
id
FROM your_table
JOIN (SELECT #row_no := 0) AS init
ORDER BY id
) AS dt ON dt.id = t1.id
SET t1.id = dt.row_num;
DB Fiddle DEMO

Insert into with multi select or multi conditions

I have a table that contains many informations:
CREATE TABLE sequences (
`id` INT(11) NOT NULL DEFAULT '0',
`name` TEXT NULL,enter code here
`nbrlsu` BIGINT(20) NULL DEFAULT NULL,
`nbrits` BIGINT(20) NULL DEFAULT NULL,
`nbrco1` BIGINT(20) NULL DEFAULT NULL,
`nbrrcbl` BIGINT(20) NULL DEFAULT NULL,
`nbrmatk` BIGINT(20) NULL DEFAULT NULL,
`nbrsequences` BIGINT(20) NULL DEFAULT NULL,
`parent_id` BIGINT(20) NULL DEFAULT NULL,
PRIMARY KEY (`id`)
);
I want to create a table based on sum of columns in the first table
for exemple I want to know te number of elements that have the same parent_id and has numbersequences>0
and I want to know for each type of sequences the number of rows that contains information:
SELECT parent_id ,
Classification,count(id) as nbrspecies,
SUM(nbrsequences) ,
SUM(nbrco1),
SUM(nbrits),
SUM(nbrlsu),
SUM(nbrrcbl),
SUM(nbrmatk)
FROM dashboard_specimen
GROUP BY parent_id
and I have an other kind of queries:
SELECT parent_id ,
count(id) as co1
FROM dashboard_specimen
WHERE nbrco1>0
GROUP BY parent_id ;
and
SELECT parent_id ,
count(id) as nbrspecies
FROM dashboard_specimen
WHERE nbrsequences>0
GROUP BY parent_id
and other types like this
and my goal in the end is to insert this information into an other table with insert select
like this:
INSERT INTO bold_namestats (id,
name,
numberofstrains,
numberofsequences,
numberofco1,
numberofits,
numberoflsu,
numberofrbcl,
numberofmatk)
SELECT parent_id ,
Classification,
count(id) as nbrspecies,
SUM(nbrsequences) ,
SUM(nbrco1),
SUM(nbrits),
SUM(nbrlsu),
SUM(nbrrcbl),
SUM(nbrmatk)
FROM dashboard_specimen
GROUP BY parent_id
I don't know if there is a simple way to do this with temp tables or something like this
If I understand well, you could do a subquery for each column you want to populate, filtering each subquery for an id.
INSERT INTO bold_namestats (id,
name,
numberofstrains,
numberofsequences,
numberofco1,
numberofits,
numberoflsu,
numberofrbcl,
numberofmatk)
select parent_id, (*select1* where parent_id=...), (*select2* where parent_id=...), ... , (*selectn* where parent_id=...)
from dashboard_specimen
group by parent_id
where select1, select2, ... , selectn are the different queries you have.
Finally I have resolved my problem using join and temp tables
INSERT INTO bold_namestats (_id,numberofstrains, numberofsequences,numberofco1,numberofits,numberoflsu,numberofrbcl,numberofmatk,numberstrainswithco1,numberstrainswithseq)
SELECT a._id ,a.numberofstrains,a.numberofsequences ,a.numberofco1,a.numberofits,a.numberoflsu,a.numberofrbcl,a.numberofmatk,b.numberofstrainswithco1,c.numberofstrainswithseq FROM bold_temp_namestats a left join bold_strainswithco1 b on a._id=b.parent_id left join bold_strainswithseq c on a._id=c.parent_id union
SELECT a._id ,a.numberofstrains,a.numberofsequences ,a.numberofco1,a.numberofits,a.numberoflsu,a.numberofrbcl,a.numberofmatk,b.numberofstrainswithco1,c.numberofstrainswithseq FROM bold_temp_namestats a right join bold_strainswithco1 b on a._id=b.parent_id left join bold_strainswithseq c on a._id=c.parent_id ;
this query is used to replace full outer join so I fill 3 tables with data and after that I insert with joinin result with left and right join and union the result to get full lines in the end

Conditional count with group by in where clause

I have a simple messaging system - keeping all the messages in a single table. Each message can(and should) be associated with one of the 3 other tables, that represent some sections of the website. Here is the create table statement
CREATE TABLE `messages` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`from_user_id` int(11) DEFAULT NULL,
`to_user_id` int(11) DEFAULT NULL,
`message` text COLLATE utf8_bin,
`table1_id` int(11) DEFAULT NULL,
`table2_id` int(11) DEFAULT NULL,
`table3_id` int(11) DEFAULT NULL,
`is_unread` tinyint(1) DEFAULT NULL,
`date` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
For each message, from table1_id, table2_id and table3_id if some column has value, it means the rest 2 are null. Here is the sqlfiddle structure and example data: http://sqlfiddle.com/#!9/b98a2/1/0.
So, table1_id, table2_id and table3_id are sort of threads, that I am using when grouping - to show the list of messages. Here is my query
SELECT
id,
table1_id,
table2_id,
table3_id,
message,
from_user_id,
to_user_id,
COUNT(table1_id) AS t1_count,
COUNT(table2_id) AS t2_count,
COUNT(table3_id) AS t3_count,
MAX(CASE WHEN to_user_id = 10 AND is_unread = 1 THEN 1 END) AS is_unread,
COUNT(CASE WHEN to_user_id = 10 THEN 1 END) AS inbox_count
FROM
messages
WHERE to_user_id = 10 OR from_user_id = 10
GROUP BY table1_id,
table2_id,
table3_id
ORDER BY id DESC
and this is in sqlfiddle http://sqlfiddle.com/#!9/b98a2/2/0
This query works fine when I have to show all the messages, but if e.g. I want to show only inbox of the user with id = 10 I have to check the condition that for each thread there is at least one received message, so for that I tried to apply the condition AND inbox_count > 0, which resulted an error Unknown column 'inbox_count' in 'where clause'.
I am trying to list messages similar to gmail - showing the number of total messages(t1_count, t2_count or t3_count) per thread, that is why I can not remove the OR from_user_id = 10 part.
Why it can not find that column and how I can apply that condition to show the list of received(outgoing) only messages.
Unless I completely misunderstand your intent... If you want to filter with inbox_count > 0 to then I think you want to add a
HAVING COUNT(CASE WHEN to_user_id = 10 THEN 1 END) > 0
after the group by clause. This would remove the "threads" that don't have any message with to_user = 10.
See this fiddle for and example.

MySQL: Update rows in table by iterating and joining with another one

I have a table papers
CREATE TABLE `papers` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(1000) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
`my_count` int(11) NOT NULL,
PRIMARY KEY (`id`),
FULLTEXT KEY `title_fulltext` (`title`),
) ENGINE=MyISAM AUTO_INCREMENT=1617432 DEFAULT CHARSET=utf8 COLLATE=utf8_bin
and another table link_table
CREATE TABLE `auth2paper2loc` (
`auth_id` int(11) NOT NULL,
`paper_id` int(11) NOT NULL,
`loc_id` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
The id papers.id from the upper table is the same one like the link_table.paper_id in the second table. I want to iterate through every row in the upper table and count how many times this its id appears in the second table and store the "count" into the column "my_count" in the upper table.
Example: If The paper with tid = 1 = paper_id appears 5 times in the table link_table, then my_count = 5.
I can do that by a Python script but it results in too many querys and I have millions of entrys so it is really slow. And I can't figure out the right syntax to make this right inside of MySQL.
This is what I am iterating about in a for-loop in Python (too slow):
SELECT count(link_table.auth_id) FROM link_table
WHERE link_table.paper_id = %s
UPDATE papers SET auth_count = %s WHERE id = %s
Could someone please tell me how to create this one? There must be a way to nest this and put it directly in MySQL so it is faster, isn't there?
How does this perform for you?
update papers a
set my_count = (select count(*)
from auth2paper2loc b
where b.paper_id = a.id);
Use either:
UPDATE PAPERS
SET my_count = (SELECT COUNT(b.paper_id)
FROM AUTH2PAPERLOC b
WHERE b.paper_id = PAPERS.id)
...or:
UPDATE PAPERS
LEFT JOIN (SELECT b.paper_id,
COUNT(b.paper_id) AS numCount
FROM AUTH2PAPERLOC b
GROUP BY b.paper_id) x ON x.paper_id = PAPERS.id
SET my_count = COALESCE(x.numCount, 0)
The COALESCE is necessary to convert the NULL to a zero when there aren't any instances of PAPERS.id in the AUTH2PAPERLOC table.
update papers left join
(select paper_id, count(*) total from auth2paper2loc group by paper_id) X
on papers.id = X.paper_id
set papers.my_count = IFNULL(X.total, 0)