I'm newbie in MySql. Supposed I have a table like this:
**Month table**
-----------------
id month data
1 1 0.5
2 1 0.8
3 2 0.12
4 2 0.212
5 2 1.4
6 3 5.7
7 4 6.8
How can I split it into different tables based on month and have those tables available in disk. If that's possible, how can I later refer to these tables later. For example:
**January table**
-----------------
id month data
1 1 0.5
2 1 0.8
**February table**
-----------------
id month data
1 2 0.12
2 2 0.212
3 2 1.4
**March table**
-----------------
id month data
1 3 5.7
**April table**
-----------------
id month data
1 4 6.8
etc.
Thank you for your help.
I looked into partition by range but I don't think it serves my purpose because it is not creating smaller tables. I was thinking of writing a procedure but don't know where to start.
If your intent is to simply speed up queries by month, just add an index to your month or timestamp column. Partitions speed things up, but they can also slow things down.
I looked into partition by range but I don't think it serves my purpose because it is not creating smaller tables.
This is incorrect.
Partitioning takes this notion a step further, by enabling you to distribute portions of individual tables across a file system according to rules which you can set largely as needed. In effect, different portions of a table are stored as separate tables in different locations.
You can alter your existing table into 12 partitions by month. If you already have a month column...
alter table month_table
partition by list(month) (
partition January values in (1),
partition February values in (1),
-- etc ---
);
And if you have a date or timestamp column, turn it into a month.
alter table month_table
partition by list(month(created_at)) (
partition January values in (1),
partition February values in (1),
-- etc ---
);
...how can I later refer to these tables later
Generally, you don't refer to the individual partitions. You insert and query the main table. The point of partitioning is to be transparent. If there is an applicable where clause that will read from the related partition.
-- This will read from the February partition.
select * from month_table where "month" = 2;
-- This will read from both the February and March partitions.
select * from month_table where "month" in (2,3);
But you can query the individual partitions with a partition clause using the name of the partition.
SELECT * FROM month_table PARTITION (January);
You generally do not need to do this except to debug what is in each partition.
Related
I have a partition by query that increments based on the number of account codes and the dates these were entered as follows
SELECT
Account,
Entry_Date,
COUNT(Account) OVER (PARTITION BY Account ORDER BY Entry_Date) AS Entry_No
FROM accounts_entries;
The new column produces the following output.
Account | Entry_Date | Entry_No
1000 2022-02-17 1
1000 2022-03-01 2
1000 2022-08-14 3
1000 2022-12-11 4
2000 2022-01-02 1
2000 2022-04-01 2
2000 2022-05-04 3
2000 2022-06-05 4
However, I cannot figure out how get this added as an actual column using ALTER TABLE without errors.
Attempting to add this using ALTER TABLE results in an Error Code: 3593. I've tried reviewing this and window functions but can't seem to find a solution that applies to PARTITION BY. I did consider joining but Entry_No really needs to be its own column that incrementally updates as new Account entries are added.
I have been struggling with the following for some time.
The server I am using has MySQL ver 5.7 installed.
The issue:
I wish to take recorded tank level readings from one table, find the difference between the last two records for a particular tank, and multiply this by a factor to get a quantity used.
The extracted quantity, if it is +ve, else 0 , then to be inserted into another table for further use.
The Quant value extracted may be +ve or -ve as tanks fill and empty. I only require the used quantity -ie falling level.
The two following tables are used:
Table 'tf_rdgs' sample;
value 1 is content height.
id
location
value1
reading_time
1
18
1500
2
18
1340
3
9
1600
4
18
1200
5
9
1400
6
18
1765
yyyy
7
18
1642
xxxx
Table 'flow' example
id
location
Quant
reading_time
1
18
5634
dd-mm: HH-mm
2
18
0
dd-mm: HH-mm
3
18
123
current time
I do not require to go back over history and am only interested in the latest level readings as a new level reading is inserted.
I can get the following to work with a table of only one location.
INSERT INTO flow (location, Quant)
SELECT t1.location, (t2.value1 - t1.value1) AS Quant
FROM tf_rdgs t1 cross join tf_rdgs t2 on t1.reading_time > t2.reading_time
ORDER BY t2.reading_time DESC limit 1
It is not particularly efficient but works and gives the following return from the above table.
location
Quant
18
123
for a table with mixed locations including a WHERE t1.location = ... statement does not work.
The problems i am struggling with are
How to nest the initial sorting by location for the subsequent inquiry of difference between the last two tank level readings.
A singular location search is ok rather than all tanks.
A Conditional INSERT to insert the 'Quant' value only if it is +ve or else insert a 0 if it is -ve (ie filling)
I have tried many permutations on these without success.
Once the above has been achieved it needs to run on a conditional trigger - based upon location of inserted data - in the tf_rdgs table activated upon each new reading inserted from the sensors on a particular tank.
I can achieve the above with the exception of the conditional insert if each tank had a dedicated table but unfortunately I cant go there due existing data structure and usage.
Any direction or assitance on parts or whole of this much appreciated.
I have a table inside my database just like the sample below and i would like to query the same data but in the Column 2 the positions of the data would be 1 row greater than the previous data.
P.S. Im actually making a system for a Electric Meter Reading and I need the Current(Column 1) and the Previous(Column 2) Data Reading, so that I could compute the total consumption of the Electric Meter. But I am having a hard time doing it. Any suggestions would be deeply appreciated. Thank You. :)
Example data:
Desired Query Output:
Keep in mind that SQL table rows have no inherent order. They're just bags of records.
You must order them based on some column value or other criterion. In your case I guess you want the most recent and the second most recent meter reading for each account. Presumably your reading table has columns something like this:
reading_id customer_id datestamp value
1 1122 2009-02-11 112
2 1234 2009-02-13 18
3 1122 2009-03-08 125
4 1234 2009-03-10 40
5 1122 2009-04-12 160
6 1234 2009-04-11 62
I guess you need this sort of result set
customer_id datestamp value previous
1122 2009-03-08 125 112
1122 2009-04-12 160 125
1234 ...etcetera.
How can you get this? For each row in the table, you need a way to find the previous reading for the same customer: that is, the row with
the same customer id
the latest datestamp that occurs before the current datestamp.
This is a job for a so-called correlated subquery. Here's the query, with its subquery. (https://www.db-fiddle.com/f/hWGAbq4uAbA5f15j7oZY9o/0)
SELECT aft.customer_id,
aft.datestamp,
( SELECT bef.value
FROM r bef /* row from table.... */
WHERE bef.datestamp < aft.datestamp /* with datestamp < present datestamp */
AND bef.customer_id = aft.customer_id /* and same customer id */
ORDER BY bef.datestamp DESC /* most recent first */
LIMIT 1 /* only most recent */
) prev,
aft.value
FROM r aft
ORDER BY aft.customer_id, aft.datestamp
Notice that dealing with the first reading for each customer takes some thought in your business process.
I have a problem with a MySQL table with over 30 MM records.
It was very slow on queries made by the key so I decided to use partitions.
after that, it became way faster, but today I was checking the partitions and something is wrong.
I did 16 partitions by key, the key was a uniqid() so they were unique but kind of sequential.
When I checked how many records each partition has, it was like
partition 0 - 3.5 MM
partition 1 - 0
partition 2 - 3.2 MM
partition 3 - 0
partition 4 - 8.5 MM
partition 5 - 0
partition 6 - 2.9 MM
partition 7 - 0
and so on
I don't care if one partition has two or three times more than others, but I don't understand why the 1, 3, 5, 7, 9, 11, 13, 15 partitions have zero records. so 8 out of 16 partitions are empty.
I thought it could be due to the sequential numbers so I changed the key to a md5 unique value, so every data starts with random data, but the pattern is the same, 8 partitions handle all the data, the other 8 are completely empty.
Why is this happening and what could I do to fix this?
thanks!
I have around 2 million records in the database and I want to us the concept of partitions in one of my batch jobs. In order to do this I need to first identify the boundary records of the partition. Can anyone help out to identify boundry values using SQL query. To illustrate consider i have student records as follows
STUDENT_ID STUDENT_NAME
1 JACK
2 SPARROW
3 JONNY
4 WALKER
5 SKY
6 DANNY
Now if i want to create 2 partitions by boundary condition of first partition will be STUDENT_ID between 1 to 3 and STUDENT_ID between 4 to 6. consider similar situation incase student_id is a string or random id. How to identify the bounday condition. Currently I am thinking of first querying all the records in the database and then partitioning them in the java code. But if I have 2 million records this is highly not recommended what should i do in this condition?
You can use limit command in mySql as follow:
SELECT...
LIMIT y OFFSET x