I know this question has been asked before and most of the answers warn about doing so or suggest a solution for MyISAM but I'm using InnoDB.
I'm trying to generate an Invoice or Bill for the user for him to give out to me (Business plan requirement) !
The thing is that in my country the reference of the ID of the bill for the same person should be ordered or he will be audited for the missing bills. Like for example he gave me one bill with 0001 and the second one is 0005. He will be interrogated for the missing 4.
So I need to have a custom auto-increment per UserID.
User 1 - idUser= 1 ,idBill = 1
User 1 - idUser= 1 ,idBill = 2
User 2 - idUsr = 2 , idBill = 1
Some threads suggested using triggers while others warned about table locks. I personally not familiar with triggers so I steer away from them since they require maintenance.
I am using Java and MySQL.
An example:
CREATE TABLE main (id INT AUTO_INCREMENT PRIMARY KEY,
primary_id CHAR(3),
secondary_id INT) ENGINE = InnoDB;
CREATE TABLE auxiliary (primary_id CHAR(3),
secondary_id INT AUTO_INCREMENT,
PRIMARY KEY (primary_id, secondary_id)) ENGINE = MyISAM;
CREATE TRIGGER generate_secondary_id
BEFORE INSERT
ON main
FOR EACH ROW
BEGIN
INSERT INTO auxiliary (primary_id) VALUES (NEW.primary_id);
SET NEW.secondary_id = LAST_INSERT_ID();
END
INSERT INTO main (primary_id) VALUES
('A01'),
('A01'),
('B01'),
('C01'),
('A01'),
('B01'),
('A01'),
('B01');
SELECT * FROM main;
id | primary_id | secondary_id
-: | :--------- | -----------:
1 | A01 | 1
2 | A01 | 2
3 | B01 | 1
4 | C01 | 1
5 | A01 | 3
6 | B01 | 2
7 | A01 | 4
8 | B01 | 3
db<>fiddle here
Related
I have a table with large number of rows. It has column like timestamp(in millis), value, and a siteId(foreign key). I want to fetch data from that of last three months with an interval in timestamp of 8 hours and I want to fetch data of all siteId in the three month timestamp. I have data in there for every 5 minutes of every siteId. If I fetch data of last three months, it is coming in millions. so I want to take data of every 8 hours. Sometimes, there can be a gap too so if a siteId was not there for the 8th hour, it should get its next data which can be 5 minutes past(or 10minutes past...) of that 8th hour.
Its hard to create a query for that and normal fetching and massaging the data in afterwards will take time.
I am using postgres, java and JPA. If I can do it via query or via some JPA utility to ease the CPU? I want to drop the time taken(right now 9 seconds for each query) to the least. Can you guys help me? Thanks in advance
My Table structure:
| timestamp | value | siteId |
|----------------|-------|--------|
| 1610370000000 | 22 | 123 |
| 1610370700000 | 21 | 123 |
| 1610370028000 | 22 | 123 |
| 1610369889000 | 23 | 123 |
| 1610370000000 | 22 | 124 |
| 1613534400000 | 21 | 124 |
| 1610369889000 | 22 | 124 |
| 1610370005000 | 23 | 125 |
So every site is having data for every 5 minutes. I want data of last three months with interval of at least 8 hours of every site. Hope this helps
Assuming you want same data structure like your example in question from last 3 months on 8 hours interval for each siteID.
Try this:
select
distinct on (siteId, "group" ) siteId, value, timestamp_,
ceil((extract(epoch from current_timestamp)*1000-timestamp_)/28800000) "group"
from test
where to_timestamp(timestamp_/1000) between current_timestamp - interval '3 month' and current_timestamp
order by 1,4,3
DEMO
Here I am dividing the difference of current_timestamp and timestamp_ field with 2880000(8*60*60*1000) to get the group and getting the first value of the group by using distinct on.
You can switch order by from order by 1,4,3 (return the value of min timestamp_ of range) to order by 1,4,3 desc (return the value of max timestamp_ of range) to check the correct result.
I am not sure about performance. But is should work better than java fetching.
If you need all data but you face issue with a transfer of huge data amount I would recommend to use pagination approach.
https://www.baeldung.com/jpa-pagination
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
I want to insert 5 million data into a 500 million table named t_phone_numbers without duplicated phones, so I select exist phones all and compare them in memory, but I got Out Of Memory ERROR because the MySQL tables have a large data.
How can I solve it?
Restriction: Mysql table t_phone_numbers cannot change, and the column phone_number is not unique. Create a new table is acceptable.
AS an example.
CREATE TABLE existing (phone VARCHAR(255))
SELECT '123456789' phone UNION ALL
SELECT '789456123' UNION ALL
SELECT '456456456' UNION ALL
SELECT '654654645' UNION ALL
SELECT '123321123' ;
SELECT * FROM existing;
| phone |
| :-------- |
| 123456789 |
| 789456123 |
| 456456456 |
| 654654645 |
| 123321123 |
CREATE TABLE new (phone VARCHAR(255) UNIQUE)
SELECT '123456789' phone UNION ALL
SELECT '464646464' UNION ALL
SELECT '123321123' ;
SELECT * FROM new;
| phone |
| :-------- |
| 123321123 |
| 123456789 |
| 464646464 |
INSERT
INTO existing (phone)
SELECT phone
FROM new
WHERE NOT EXISTS ( SELECT NULL
FROM existing
WHERE new.phone = existing.phone );
SELECT * FROM existing;
| phone |
| :-------- |
| 123456789 |
| 789456123 |
| 456456456 |
| 654654645 |
| 123321123 |
| 464646464 |
db<>fiddle here
The most problem is SELECT part in INSERT. If neither existing nor new table's phone column is indexed then the process may be infinite..
So the recommendations - index this column in new table and (if possible) in existing table. Maybe even create a copy of existing table (phone column only), index it and use in SELECT part.
Anycase this SELECT optimization is the most problem (indexing, using LEFT JOIN, etc.), the insertion itself will be relatively fast.
I am working on a project Spring and Java, generated using JHipster. I want to filter on table that doesn't have a direct relationship with another.
My purpose is almost asked in a previous similar question
Write Spring Specification with multiple inner join & other conditions
But in my case , I ve two unrelated entities :
Consultant (id : Long , FullName : string , profileRank : Enum of string )
Rank (id : Long , level : Enum of string , rate : Double )
Consultant | Rank
|
id | FullName | profileRank | id | level | rate
1 | aaaaa | 'ONE' | 1 | 'ONE' | 1
2 | bbbbbb | 'THREE' | 2 | 'TWO' | 2
3 | cccccc | 'FOUR' | 3 | 'THREE' | 3
4 | dddddd | 'THREE' | 4 | 'FOUR' | 4
I want to filter consultant list by rate using level
Example : get consultants with rate greater than 3
Expected result
id | FullName | profileRank
3 | cccccc | 'FOUR'
I ve searched in documentation and many articles without get it to work please how to achieve that .
You don't need to write a specification for your case.
Fetch all the ranks with levels and rates
Filter these values and keep only the ones greater than 3 (step 1 and 2 can be combined). The result will be a List<Rank> that contains only FOUR rank
list.stream(rank => rank.level).collect(toList())
The result of step 3 will be passed to a repository method like List<Consultant> findByProfileRankIn(List<String> levelNames)
Another alternative would be joins something like this Joining tables without relation using JPA criteria
If you still want a spec that's also possible. Spring Data Join with Specifications
I have an SQLite table like:
+---+-------------+----------------+
|_id| lap_time_ms |formatted_elapse|
+---+-------------+----------------+
| 1 | 5600 | 00:05.6 |
| 2 | 4612 | 00:04.6 |
| 3 | 4123 | 00:04.1 |
| 4 | 15033 | 00:15.0 |
| 5 | 4523 | 00:04.5 |
| 6 | 6246 | 00:06.2 |
Where lap_time_ms is an of the type long and represents the amount of time in milliseconds for a lap while formatter_elapse is a String that represents the formatted (displayable) form of the first column (elapse).
My question is that if I want to add (say) 5 seconds (5000) to each lap_time_ms then I use a statement like:
DB.execSQL("update table_name set KEY_ELAPSE=KEY_ELAPSE+5000);
Which works fine however the problem is that formatted_elapse still retains its outdated value!
So, what is the best way to update the values in the formatted_elapse column if I have a function like:
public static String getFormattedTime(long milliseconds) {
// custom code that processes the long
return processedString;
}
It may be a long shot (metaphorically speaking of course ;) but is it possible to have SQLite link the two columns such that if I update a lap_time_ms row, the formatted_elapse will automatically update appropriately.
Thanks in advance!
In theory, it would be possible to create a trigger to update that column, but only if the formatting can be done with some built-in SQLite function (Android does not allow user-defined functions):
CREATE TRIGGER update_formatted_elapse
AFTER UPDATE OF lap_time_ms ON MyTable
FOR EACH ROW
BEGIN
UPDATE MyTable
SET formatted_elapse = strftime('%M:%f', NEW.lap_time_ms, 'unixepoch')
WHERE _id = NEW._id;
END;
However, it would be bad design to store the formatted string in the database; it would be duplicated information that is in danger of becoming inconsistent.
Drop the formatted_elapse column and just call getFormattedTime in your code whenever you need it.
I have three tables which are customer, stock,invoice.
customer table PK is CNo(Customer No)
stock table PK is PNo(Product NO)
invoice table gets the both PKs(CNo from customer table and PNo from stock table) as Its Associate key .
What I want to do is , update stock table QuntyAvailable column through invoice table.
Ex. when a customer gets 2 Quantities from PNo 2 which is Dettol , it automatically update stock table QuntyAvailable column for above product's own row to 18( QuntyAvailable-Qty).
I tried many times with various queries but I got only errors. like PK cannot be Updated ..
bla bla bla......
Please help me on this Thank you.
customer table
CNo(PK) | Name | Address
1 | Jhon | 23, Hill St, NY.
2 | Sam | 24, Bejin , Chaina.
3 | Nic | 25, London ,England.
stock table
PNo(PK) | Description | Each Price | QntyAvailable
1 | Dettol | $2 | 10
2 | Astra | $5 | 20
invoice table
CNo(PK) | PNo(PK) | Qty | value
1 | 2 | 2 | $10
2 | 1 | 3 | $6
after the update done I want the stock table like this...
stock table
PNo(PK) | Description | Each Price | QntyAvailable
1 | Dettol | $2 | 7
2 | Astra | $5 | 18
Please help me .. I m using mysql server and netbeans IDE
My query -------------
s.executeUpdate("INSERT INTO invoice(CNo,PNo,Qty,Value) VALUES('1','2','10','150')"); s.executeUpdate("UPDATE stock set QuntyAvailable=QuntyAvailable-10 WHERE Pno ='2'");
If you want to update stocks table when you do an insert in invoice, you can either do the update after the insert with the data you have for the insert (like the one you tried, the only thing that looks wrong is the ='2' that looks like it should be only =2) or do it in a trigger, having the newly inserted values feed the update:
CREATE TRIGGER updateStock AFTER INSERT ON invoice
FOR EACH ROW BEGIN
UPDATE stock set QntyAvailable=QntyAvailable- new.Qty WHERE Pno =new.Pno;
END;
//
You can check this fiddle to see it working.
P.S.
You really should have an InvoiceID. The way you are constructing it, you are not allowing a customer to purchase the same product twice.
P.S. 2 - Your error creating the trigger is related to not setting the DELIMITER.
If you don't set it the statement will end at the first ; You need to set it before the trigger and end your trigger definition with it. After that you can set the delimiter back to ;.
DELIMITER //
CREATE TRIGGER updateStock AFTER INSERT ON invoice
FOR EACH ROW BEGIN
UPDATE stock set QntyAvailable=QntyAvailable- new.Qty WHERE Pno =new.Pno;
END;
//
DELIMITER ;