Using MySql WorkBench, in table1 I want to put in every cell of the column item_quantiy_total de sum of the column item_quantity. I tried the expression SUM(item_quantity), but that was rejected. What would be the correct expression?
Lets say you have such a table:
mysql> SELECT * FROM TestTable;
+---------------+
| item_quantity |
+---------------+
| 12 |
| 25 |
| 16 |
| 90 |
| 120 |
+---------------+
5 rows in set (0.01 sec)
USE window functions to achieve it:
mysql> SELECT item_quantity, SUM(item_quantity) OVER() AS item_quantity_total FROM TestTable;
+---------------+--------------------+
| item_quantity | item_quantiy_total |
+---------------+--------------------+
| 12 | 263 |
| 25 | 263 |
| 16 | 263 |
| 90 | 263 |
| 120 | 263 |
+---------------+--------------------+
5 rows in set (0.00 sec)
Related
I have the table posts, where id_post is primary key & autoincrement
id_post | post
1 hi1
3 hi3
27 hi27
45 hi45
67 hi67
69 hi69
I want to update id_post in order it to get its row position in the table
id_post | post
1 hi1
2 hi3
3 hi27
4 hi45
5 hi67
6 hi69
How could it be done?
I was thinking using ROW_NUMBER()
Run these commands:
SET #x = 0;
ALTER TABLE `posts` AUTO_INCREMENT = 1;
UPDATE `posts` SET `id_post` = #x:= #x + 1;
You can use set oprion as bellow :
before
+--------+--------+
|id_post | itemID |
+--------+--------+
| 1 | hi1 |
| 3 | hi3 |
| 27 | hi27 |
| 45 | hi45 |
| 67 | hi67 |
| 69 | hi69 |
+--------+--------+
after
--------------------
mysql> SET #nbr=0;
Query OK, 0 rows affected (0.00 sec)
mysql> update posts set id=#nbr:=#nbr+1
+--------+--------+
|id_post | post |
+--------+--------+
| 1 | hi1 |
| 2 | hi3 |
| 3 | hi27 |
| 4 | hi45 |
| 5 | hi67 |
| 6 | hi69 |
+--------+--------+
6 rows in set (0.00 sec)
I want to combine following two queries to one
first query:-
SELECT * FROM `same_table` WHERE `same_column`="same_string";
second query:-
DELETE FROM `same_table` WHERE `same_column`="same_string";
I'm new to mysql.
I think your goal is after select finished you must delete the selected data. Use this query.
DELETE FROM `same_table` WHERE `same_column`="same_string" and (SELECT * FROM `same_table` WHERE `same_column`="same_string");
You can simply append the two queries together in a single query. As long as you have the semi-colon separating them, they will both execute.
Example of a test DB I have running: This is holding click numbers for some buttons I set up using AJAX. I ran 2 queries basically similar queries to yours and I simply appended the two queries together.
mysql> SELECT * FROM clicks;
+-----------------+------+---------------------+
| category | num | lasttime |
+-----------------+------+---------------------+
| Five | 13 | 2017-11-23 22:50:02 |
| One | 25 | 2017-11-23 22:49:54 |
| Two | 40 | 2017-11-23 22:50:00 |
| Three | 60 | 2017-11-23 22:50:00 |
| Six | 4 | 2017-11-23 22:50:02 |
| Seven | 4 | 2017-11-23 22:50:03 |
| Eight | 14 | 2017-11-23 16:28:19 |
| Four | 7 | 2017-11-23 22:50:01 |
| Random Button 1 | 29 | 2017-11-23 16:40:31 |
+-----------------+------+---------------------+
9 rows in set (0.00 sec)
mysql> SELECT num FROM clicks WHERE category='Random Button 1';
+------+
| num |
+------+
| 29 |
+------+
1 row in set (0.00 sec)
mysql> SELECT num FROM clicks WHERE category='Random Button 1'; DELETE FROM clicks WHERE category='Random Button 1';
+------+
| num |
+------+
| 29 |
+------+
1 row in set (0.00 sec)
Query OK, 1 row affected (0.00 sec)
mysql>
After running SELECT * FROM clicks; again, this is the output:
mysql> SELECT * FROM clicks;
+----------+------+---------------------+
| category | num | lasttime |
+----------+------+---------------------+
| Five | 13 | 2017-11-23 22:50:02 |
| One | 25 | 2017-11-23 22:49:54 |
| Two | 40 | 2017-11-23 22:50:00 |
| Three | 60 | 2017-11-23 22:50:00 |
| Six | 4 | 2017-11-23 22:50:02 |
| Seven | 4 | 2017-11-23 22:50:03 |
| Eight | 14 | 2017-11-23 16:28:19 |
| Four | 7 | 2017-11-23 22:50:01 |
+----------+------+---------------------+
8 rows in set (0.00 sec)
So yes, you can have as many statements within the same query. They just have to be separated by a semi-colon.
This also applies to PDO prepared statements, assuming you're doing this with PHP.
This is my table with id field as unsigned tinyint PRIMARY KEY with NOT NULL and AUTO_INCREMENT.
+----+
| id |
+----+
| 1 |
| 4 |
|254 |
|255 |
+----+
My application is an embedded application so I am using the small datatypes like tinyint. My total count of id values wont go upto 255. But in case if the in between values are deleted for number of times then inserting the new id value will definitely reach 255 sooner or later.
I have some questions,
Is it possible to set the auto increment feature such that it will be insert the new id to the not existing greater value (here 2)?
If not please suggest some way to handle this issue other than using higher data type for id and updating the higher id values after deleting an id (like if I delete id = 2 update all the id values greater than 2 to id-1 so that all the values remain in sequence while inserting new value).
Append your fields for insert. this will use the lowest free id
INSERT INTO ai (id) (
SELECT a.id+1 FROM ai a
LEFT JOIN ai b ON a.id+1 = b.id
WHERE b.id IS NULL LIMIT 1
)
OR to get also 1
SELECT a.id+1 FROM (
SELECT 0 AS id UNION SELECT id FROM ai
) AS a
LEFT JOIN ai b ON a.id+1 = b.id
WHERE b.id IS NULL
ORDER by a.id ASC
LIMIT 1;
I can't think why you choose to be bound by this arbitrary limit. That said, if were to do this then I would construct a table with all possible integers (1-255) and a flag indicating whether the value was currently in use. So a DELETE becomes UPDATE x SET flag = 0 WHERE id = n. Then the query to find the lowest 0 flag becomes trivial.
#
Edge Goldberg - if you want to reorder the entrys and use auto_increment use this. Then also lst_insertid will work -- : -- After DELETE a ROW
UPDATE abc , (SELECT #nr:=0) AS INIT SET a := #nr := (#nr+1);
ALTER TABLE abc AUTO_INCREMENT=1;
-- INSERT a new one
INSERT INTO abc (a) VALUES(1234);
SELECT LAST_INSERT_ID();
Here is the Sample for set auto_increment
MariaDB []> select * from abc;
+-------+------+
| a | b |
+-------+------+
| 00001 | 2 |
| 00002 | 3 |
| 00004 | 5 |
| 00005 | 6 |
| 00007 | 8 |
| 00008 | 9 |
| 00009 | 10 |
| 00010 | 11 |
| 00012 | 13 |
| 00013 | 14 |
| 00014 | 15 |
| 00015 | 16 |
| 00016 | 17 |
| 00017 | 18 |
| 00018 | 19 |
| 00033 | 34 |
| 00077 | 78 |
| 00555 | 556 |
+-------+------+
18 rows in set (0.00 sec)
MariaDB []> -- After DELETE a ROW
MariaDB []> UPDATE abc , (SELECT #nr:=0) AS INIT SET a := #nr := (#nr+1);
Query OK, 16 rows affected (0.03 sec)
Rows matched: 18 Changed: 16 Warnings: 0
MariaDB []> ALTER TABLE abc AUTO_INCREMENT=1;
Query OK, 0 rows affected (0.00 sec)
Records: 0 Duplicates: 0 Warnings: 0
MariaDB []> select * from abc;
+-------+------+
| a | b |
+-------+------+
| 00001 | 2 |
| 00002 | 3 |
| 00003 | 4 |
| 00004 | 5 |
| 00005 | 6 |
| 00006 | 7 |
| 00007 | 8 |
| 00008 | 9 |
| 00009 | 10 |
| 00010 | 11 |
| 00011 | 12 |
| 00012 | 13 |
| 00013 | 14 |
| 00014 | 15 |
| 00015 | 16 |
| 00016 | 17 |
| 00017 | 18 |
| 00018 | 19 |
+-------+------+
18 rows in set (0.00 sec)
MariaDB []> INSERT INTO abc (a) VALUES(NULL);
Query OK, 1 row affected (0.01 sec)
MariaDB []> SELECT LAST_INSERT_ID();
+------------------+
| LAST_INSERT_ID() |
+------------------+
| 19 |
+------------------+
1 row in set (0.00 sec)
MariaDB []> select * from abc;
+-------+------+
| a | b |
+-------+------+
| 00001 | 2 |
| 00002 | 3 |
| 00003 | 4 |
| 00004 | 5 |
| 00005 | 6 |
| 00006 | 7 |
| 00007 | 8 |
| 00008 | 9 |
| 00009 | 10 |
| 00010 | 11 |
| 00011 | 12 |
| 00012 | 13 |
| 00013 | 14 |
| 00014 | 15 |
| 00015 | 16 |
| 00016 | 17 |
| 00017 | 18 |
| 00018 | 19 |
| 00019 | 20 |
+-------+------+
19 rows in set (0.01 sec)
MariaDB []>
I have normalize my table to separate beetwen tb_header and tb_detail.
This is the tb_repair detail.
mysql> SELECT DETAIL_ID, REPAIR_ESTIMATE_ID, REMARKS, MANHOUR FROM tb_repair_detail;
+-----------+--------------------+----------------------+---------+
| DETAIL_ID | REPAIR_ESTIMATE_ID | REMARKS | MANHOUR |
+-----------+--------------------+----------------------+---------+
| 9 | 50 | Anda | 12.00 |
| 10 | 50 | Jika | 10.00 |
| 11 | 51 | ACRYLIC | 12.00 |
| 12 | 51 | Pembersihan exterior | 10.00 |
| 13 | 51 | Repairing | 10.00 |
+-----------+--------------------+----------------------+---------+
5 rows in set (0.00 sec)
Now, for more readable to user, now I want to create a view that would be like this :
mysql> SELECT a.REPAIR_ESTIMATE_ID , a.EIR_REF ,
-> (SELECT b.NAMA FROM tb_customer_master b WHERE a.COSTUMER_ID = b.COSTUMER_ID) AS "NAMA_CUSTOMER"
-> from tb_master_repair_estimate a ;
+--------------------+---------+----------------------+
| REPAIR_ESTIMATE_ID | EIR_REF | NAMA_CUSTOMER |
+--------------------+---------+----------------------+
| 50 | 1545053 | APL |
| 51 | 1545052 | APL |
+--------------------+---------+----------------------+
2 rows in set (0.00 sec)
My question is, I want to put the manhour total based REPAIR_ESTIMATE_ID How to put this manhour total in this view ? I know the query to sum() each REPAIR ESTIMATE_ID like
mysql> SELECT SUM(MANHOUR) AS TOTAL FROM tb_repair_detail a WHERE a.REPAIR_ESTIMATE_ID = 51
mysql> SELECT SUM(MANHOUR) AS TOTAL FROM tb_repair_detail a WHERE a.REPAIR_ESTIMATE_ID = 50;
+-------+
| TOTAL |
+-------+
| 22.00 |
+-------+
+-------+
| TOTAL |
+-------+
| 32.00 |
+-------+
1 row in set (0.00 sec)
But, how I get them into those view ?
SELECT a.repair_estimate_id, a.eir_ref, b.nama AS nama_customer, c.total
FROM tb_master_repair_estimate a, tb_customer_master b,
(SELECT repair_estimate_id, SUM(manhour) AS total
FROM tb_repair_detail
GROUP BY repair_estimate_id) c
WHERE a.repair_estimate_id = c.repair_estimate_id
AND a.COSTUMER_ID = b.COSTUMER_ID
should, I think, give the desired result set. Make that your view's query and you ought to be set.
Note the clause GROUP BY repair_estimate_id which causes the subquery to compute SUM(manhour) for each distinct value of repair_estimate_id.
I have following MySQL query result, I want only UserName first part before # it need 10000013 part only, I want to remove example.com part, it is possible by TRIM?
mysql> SELECT UserName,DAY(AcctStartTime), COUNT(ResponseCode='200') FROM table201412 WHERE UserName='10000013#example.com' GROUP BY DATE(AcctStartTime);
+---------------------------+--------------------+------------------------------+
| UserName | DAY(AcctStartTime) | COUNT(ResponseCode='200') |
+---------------------------+--------------------+------------------------------+
| 10000013#example.com | 1 | 3 |
| 10000013#example.com | 2 | 5 |
| 10000013#example.com | 3 | 3 |
+----------------------+--------------------+------------------------------+
10 rows in set (0.00 sec)
I need following result:
+---------------------------+--------------------+------------------------------+
| UserName | DAY(AcctStartTime) | COUNT(ResponseCode='200') |
+---------------------------+--------------------+------------------------------+
| 10000013 | 1 | 3 |
| 10000013 | 2 | 5 |
| 10000013 | 3 | 3 |
+---------------------------+--------------------+------------------------------+
10 rows in set (0.00 sec)
The easiest way is to use substring_index():
select substring_index(UserName, '#', 1) as EmailName
In your query, that would be:
SELECT substring_index(UserName, '#', 1) as EmailName, DAY(AcctStartTime), COUNT(ResponseCode='200')
FROM table201412
WHERE UserName='10000013#example.com'
GROUP BY DATE(AcctStartTime);