mySQL : How to code query - mysql

I have 2 tables clients and grades where clients has a grade column with indices from 1 to 10. Those indices correspond to the ID's in the grades table (of course). Let's say a client has the indices 1,5,8 in the clients.grade column than I want to fetch * from those rows in the grades table.
My first approach was to use a grade field of type char(20) in the client table and fill it with indices separated by commas like 1,5,8 or others numbers. Then reading those values from one client from the client table I explode (PHP) the result and getting an array with 3 (or more) single values. Then in a following query I select all those rows in the grade table .
Now one question is wether to use a char field or an enumeration field and the other (general) question is how to make a simple, clever query for the entire task.
I did not code it yet. The grades table will have max. 10 rows, where as the client table has around 2.000 rows growing up to max. 5.000 rows. I hope I could describe my approach understandable.
Any suggestions are welcome

Split the grade column into a new table (client_grade?) containing clientId and grade, and have multiple records for each client. The grades for a client can then be retrieved using a JOIN from the clients to the clients_grade table on the client field
Each field in a table should hold a single piece of information and comma-separating values will cause you extra processing. Using a separate table will also aid you if you want to find out who got a particular grade etc

Related

MySQL database re-orders entries automatically

I have created a MySQL database using MySQL Workbench. In there, I have created a table, the first entries of which are:
id firstName lastName
1 John Smith
2 Emma Richards
Every column contains VARCHAR characters - even the id, it is NOT an integer.
For some reason, however, MySQL seems to re-order the entries:
id firstName lastName
1 John Smith
10 Karen Hill
I don't want MySQL to re-order my entries. When I retrieve the entries from the database, I want them to appear exactly in the order that I have inserted them into the database.
Previously to creating the MySQL database, I have used a SQLite database, which does not re-order the entries.
What might be the reason for this and how can I change it?
I don't want MySQL to re-order my entries. When I retrieve the entries from the database, I want them to appear exactly in the order that I have inserted them into the database.
SQL tables represent unordered (multi)sets. Period. When you query a table in any database, the ordering is not guaranteed unless you include an order by. This is even true in SQLite, as this DB fiddle demonstrates.
In most databases, if you want to capture the insertion order, then you need some sort of column that captures the ordering. There are two common methods:
An identity or auto_increment column that captures the insertion order.
A datetime/timestamp column that captures the date time. This does not always work, because there can be ties.
Then, when you query the table, you need to use order by on the column.
If your first column represents the ordering but happens to be stored as a string, then you can simply use:
order by (id + 0)

Can I create a mapping from interger values in a column to the text values they represent in sql?

I have a table full of traffic accident data with column headers such as 'Vehicle_Manoeuvre' which contains integers for example 13 represents the vehicle manoeuvre which caused the accident was 'overtaking moving vehicle'.
I know the mappings from integers to text as I have a (quite large) excel file with this data.
An example of what I want to know is percentage of the accidents involved this type of manoeuvre but I don't want to have to open the excel file and find the mappings of integers to text every time I write a query.
I could manually change the integers of all the columns (write query with all the possible mappings of each column, add them as new column, then delete the orginial columns) but this sould take a long time.
Is it possible to create some type of variable (like an array with first column as integers and second column with the mapped text) that SQL could use to understand how text relates to the integers allowing me to write a query below:
SELECT COUNT(Vehicle_Manoeuvre) FROM traffictable WHERE Vehicle_Manoeuvre='overtaking moving vehicle';
rather than:
SELECT COUNT(Vehicle_Manoeuvre) FROM traffictable WHERE Vehicle_Manoeuvre=13;
even though the data in the table is still in integer form?
You would do this with a Maneeuvres reference table:
create table Manoeuvres (
ManoeuvreId int primary key,
Name varchar(255) unique
);
insert into Manoeuvres(ManoeuvreId, Name)
values (13, 'Overtaking');
You might even have such a table already, if you know that 13 has a special meaning.
Then use a join:
SELECT COUNT(*)
FROM traffictable tt JOIN
Manoeuvres m
ON tt.Vehicle_Manoeuvre = m.ManoeuvreId
WHERE m.name = 'Overtaking';

Mysql Auto Increment For Group Entries

I need to setup a table that will have two auto increment fields. 1 field will be a standard primary key for each record added. The other field will be used to link multiple records together.
Here is an example.
field 1 | field 2
1 1
2 1
3 1
4 2
5 2
6 3
Notice that each value in field 1 has the auto increment. Field 2 has an auto increment that increases slightly differently. records 1,2 and 3 were made at the same time. records 4 and 5 were made at the same time. record 6 was made individually.
Would it be best to read the last entry for field 2 and then increment it by one in my php program? Just looking for the best solution.
You should have two separate tables.
ItemsToBeInserted
id, batch_id, field, field, field
BatchesOfInserts
id, created_time, field, field field
You would then create a batch record, and add the insert id for that batch to all of the items that are going to be part of the batch.
You get bonus points if you add a batch_hash field to the batches table and then check that each batch is unique so that you don't accidentally submit the same batch twice.
If you are looking for a more awful way to do it that only uses one table, you could do something like:
$batch = //Code to run and get 'SELECT MAX(BATCH_ID) + 1 AS NEW_BATCH_ID FROM myTable'
and add that id to all of the inserted records. I wouldn't recommend that though. You will run into trouble down the line.
MySQL only offers one auto-increment column per table. You can't define two, nor does it make sense to do that.
Your question doesn't say what logic you want to use to control the incrementing of the second field you've called auto-increment. Presumably your PHP program will drive that logic.
Don't use PHP to query the largest ID number, then increment it and use it. If you do your system is vulnerable to race conditions. That is, if more than one instance of your PHP program tries that simultaneously, they will occasionally get the same number by mistake.
The Oracle DBMS has an object called a sequence which gives back guaranteed-unique numbers. But you're using MySQL. You can obtain unique numbers with a programming pattern like the following.
First create a table for the sequence. It has an auto-increment field and nothing else.
CREATE TABLE sequence (
sequence_id INT NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`sequence_id`)
)
Then when you need a unique number in your program, issue these three queries one after the other:
INSERT INTO sequence () VALUES ();
DELETE FROM sequence WHERE sequence_id < LAST_INSERT_ID();
SELECT LAST_INSERT_ID() AS sequence;
The third query is guaranteed to return a unique sequence number. This guarantee holds even if you have dozens of different client programs connected to your database. That's the beauty of AUTO_INCREMENT.
The second query (DELETE) keeps the table from getting big and wasting space. We don't care about any rows in the table except for the most recent one.

random of function in sql for two different fields which are in two different tables

I want to perform a random function rand(100001, 1000000) which have to generate random no s which has to be unique in two different field.
To explain it clearly
I have two tables say table A which has a record with status Submitted, Approved and table B which have only records with status Rejected.
I am having a field called ackno in table A as well as table B which needs to be random no and unique in comparison with both table field.
Is this possible ? Can anybody give a solution ?
A random number won't be unique. In this case you have 999.999 numbers, based on the number of records you can calculate the probability that 2 numbers are the same.
I see 2 ways to ensure a unique value.
First of all you could use autoincrement. Let table A start with 1 and table B start with 1.000.000. As long as table A has less than a million rows, you're good.
Second is to use the uuid. A UUID is a 128-bit number represented by a utf8 string of five hexadecimal numbers in aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee format.
Note that both methods are deliver guessable values. If that's a problem, you could add a random number to it and encode it, like:
SELECT SHA2(CONCAT(UUID(), RAND()), 256);

MYSQL Query Speed (Search vs Query)

I don't have my server up and running yet, so unfortunately I can't test yet, but I was hoping you could shed some light on a question I have.
So, Table A has an inverse one-to-many relationship with Table B, so would it be better to store the ID's of Table B in Table A search by ID, or would it be better/faster to query Table B for all results where it's Table A ID is equal to my Table A's ID?
Basically Search (Search for row based on ID) vs Query (Grab all rows that have a certain value).
As long as the column containing the ID in B is a (foreign) key. It is most certainly faster. Storing a non-scalars (ie. lists) in columns in a database is generally a bad idea.