How to separate multiple data in one row to multiple rows in SQL - mysql

I have following tables in my application:
Table-1
--------------------------------------
| id | column_2(array_type) |
--------------------------------------
| 1 | [20,21,22] |
--------------------------------------
Table-2
---------------------------------------
| id | column_2(array_type) |
---------------------------------------
| 3 | [31,32] |
---------------------------------------
Now I want to create a view as follows:
-----------------------------------------------------------------
| id | Table_1_id | Table_2_id | column_2 |
-----------------------------------------------------------------
| 1 | 1 | nil | 20 |
-----------------------------------------------------------------
| 2 | 1 | nil | 21 |
-----------------------------------------------------------------
| 3 | 1 | nil | 22 |
-----------------------------------------------------------------
| 4 | nil | 3 | 31 |
-----------------------------------------------------------------
| 5 | nil | 3 | 32 |
-----------------------------------------------------------------
The view should have single row entry for every item in column_2'.
Am unable to split the column_2's array content to individual row and assign corresponding table's id to it.
Any help or reference would be very helpful. I do not have much experience with SQL.
Couldn't find much on this in google.

Related

Create an updated count column using EXISTING count column in MySQL

I have a table called transactions that looks like this:
transactions:
| id | PartNumber | Quantity |
I know that I can use the COUNT property in MySQL, which would give me the the duplicate part numbers in a new column called total_quantity:
SELECT COUNT(transactions.id) AS total_quantity
FROM transactions
GROUP BY transactions.PartNumber
However, now I already have an existing quantity column and want to compute a new count quantity taking into account the previous one as well and updating it in the existing quantity column
What's the most efficient way of doing this?
For example: I want to go from this:
transactions
| id | PartNumber | Quantity |
| 1 | 123 | 1 |
| 2 | 124 | 2 |
| 3 | 125 | 2 |
| 4 | 124 | 2 |
| 5 | 124 | 3 |
| 6 | 126 | 4 |
| 7 | 125 | 1 |
| 8 | 127 | 2 |
To this:
transactions
| id | PartNumber | Quantity |
| 1 | 123 | 1 |
| 2 | 124 | 7 |
| 3 | 125 | 3 |
| 4 | 126 | 4 |
| 5 | 127 | 2 |
You can use this sql request :
SELECT PartNumber, sum(Quantity) as 'SumQuantity' FROM transactions GROUP BY PartNumber
It will gives you sometings like this :
transactions
| PartNumber | SumQuantity |
| 123 | 1 |
| 124 | 7 |
| 125 | 3 |
| 126 | 4 |
| 127 | 2 |
You can find a code sample on SQL Fiddle

MYSQL: Count the number of row in one table based on the join of two other tables

I have three tables, Entries, Institution and Doctors. Here is a minimal example fo the table data:
ENTRIES
| keyid | doctorid |
---------------------
| 1 | 23 |
| 2 | 13 |
| 3 | 23 |
| 4 | 13 |
| 5 | 23 |
| 6 | 42 |
| 7 | 5 |
INSTITUTION
| name |
----------
| One |
| Two |
| Three |
| Four |
| Five |
| Six |
DOCTORS
| uid | inst |
-----------------------
| 23 | Three |
| 13 | Six |
| 3 | Four |
| 42 | Six |
| 5 | One |
What I need to know is the number of entries that I have for each institution. However the institutions are linked to the entries through the DOCTORS table. So the result in this case should give me this:
RESULTS
| name | count |
--------------------
| One | 1 |
| Two | 0 |
| Three | 3 |
| Four | 0 |
| Five | 0 |
| Six | 3 |
I have no idea how to even start writing this query. Any help would be greatly appreciated.
This can be solved with an aggregated query that JOINs all three tables, like :
SELECT
i.name,
COALESCE(COUNT(e.keyid), 0) cnt
FROM
institution i
LEFT JOIN doctors d ON d.inst = i.name
LEFT JOIN entries e ON e.doctorid = d.uid
GROUP BY i.name
Using your sample data, this demo on DB Fiddle returns :
| name | cnt |
| ----- | --- |
| One | 1 |
| Two | 0 |
| Three | 3 |
| Four | 0 |
| Five | 0 |
| Six | 3 |
PS : depending on your data, you might want to use COUNT(DISTINCT e.keyid).

how to update child table in mysql

I have have here an example table.incident table
+-------------+----------------------+
| incident_id | incident_description |
+-------------+----------------------+
| 1 | Accident |
| 2 | Homicide |
| 3 | Theft |
+-------------+----------------------+
incident_detail table:
+--------------------+-------------+-------------+
| incident_detail_id | person_name | incident_id |
+--------------------+-------------+-------------+
| 1 | errol | 1 |
| 2 | neo | 1 |
| 3 | aj | 1 |
| 4 | mark | 2 |
| 5 | calma | 2 |
| 6 | allan | 2 |
| 7 | dave | 3 |
| 8 | paul | 3 |
+--------------------+-------------+-------------+
I am providing a grid view like view that would allow the user to remove and add items in the incident_detail table. My question is, how can i update the incident_detail table? i am ok with adding new items, but removal. I don't know. Should i empty the entire table and insert the new items that the user added. But the problem here is that the existing items that weren't removed will be deleted and inserted again.
If you don't care about the incident_detail_id column incrementing more than it needs to, you can simply delete and re-insert the records, regardless of whether you changed the details for an incident.
It makes for easier SQL code but it does mean on each edit your IDs will go up. Assuming you're auto-incrementing.
After adding detail to Homicide you'll end up with:
+--------------------+-------------+-------------+
| incident_detail_id | person_name | incident_id |
+--------------------+-------------+-------------+
| 1 | errol | 1 |
| 2 | neo | 1 |
| 3 | aj | 1 |
| 9 | mark | 2 |
| 10 | calma | 2 |
| 11 | allan | 2 |
| 12 | new | 2 |
| 7 | dave | 3 |
| 8 | paul | 3 |
+--------------------+-------------+-------------+
If you're happy with that:
DELETE FROM incident_detail WHERE incident_id = 2;
INSERT INTO incident_detail (person_name, incident_id)
VALUES
('mark', 2)
('calma', 2)
('allan', 2)
('new', 2);

How to match comma delimited value with other column in mySql

I have following two tables:
user:
+---------+--------------+
| user_id | skills |
+---------+--------------+
| 1 | 1,2,3,5,4,14 |
| 2 | 1,2,3 |
| 3 | 3,4,5 |
| 4 | 1,2 |
+---------+--------------+
pskills:
+-----+--------+------+----------+
| PID | SKILLS | SPLI | status |
+-----+--------+------+----------+
| 1 | 2,4 | 1 | |
| 1 | 1 | 1 | required |
+-----+--------+------+----------+
I want to match values of SKILLS columns of table pskills. Such as if query is done with first row of pskills and join with user table then it will return User ID 1 because SKILLS 2,4 match with user id 1 only. How can i do this easily?
Never store multiple values in one column!
You should normalize your tables like this
**user**
+---------+--------------+
| user_id | skills |
+---------+--------------+
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
| 1 | ... |
| 2 | 1 |
| 2 | 2 |
| | ... |
+---------+--------------+
**pskills**
+-----+--------+------+----------+
| PID | SKILLS | SPLI | status |
+-----+--------+------+----------+
| 1 | 2 | 1 | |
| 1 | 4 | 1 | |
| 1 | 1 | 1 | required |
+-----+--------+------+----------+

Tricky database design

I need to design a database to store user values : for each user, there is a specific set of columns.
For instance, Jon wants to store values in a table with 2 columns : name, age.
And Paul wants to store values in a 3 columns table : fruit, color, weight.
At this point, I have 2 options.
Option 1 - Store data as text values
I would have a first table 'profiles' with the users' preferences :
+----+---------+--------+-------------+
| id | user_id | label | type |
+----+---------+--------+-------------+
| 1 | 1 | name | VARCHAR(50) |
| 2 | 1 | age | INT |
| 3 | 2 | fruit | VARCHAR(50) |
| 4 | 2 | color | VARCHAR(50) |
| 5 | 2 | weight | DOUBLE |
+----+---------+--------+-------------+
And then store the datas as text in another table :
+----+------------+--------+
| id | id_profile | value |
+----+------------+--------+
| 1 | 1 | Aron |
| 2 | 2 | 17 |
| 3 | 1 | Vince |
| 4 | 2 | 27 |
| 5 | 1 | Elena |
| 6 | 2 | 78 |
| 7 | 3 | Banana |
| 8 | 4 | Yellow |
| 9 | 5 | 124.8 |
+----+------------+--------+
After that, I would programatically create and populate a clean table.
Option 2 - One column per type
On this option, I would have a first table 'profiles2' like that :
+----+---------+--------+------+
| id | user_id | label | type |
+----+---------+--------+------+
| 1 | 1 | name | 3 |
| 2 | 1 | age | 1 |
| 3 | 2 | fruit | 3 |
| 4 | 2 | color | 3 |
| 5 | 2 | weight | 2 |
+----+---------+--------+------+
with the type corresponding of a set of type : 1=INT , 2=DOUBLE , 3=VARCHAR(50)
And a data table like that :
+----+-------------+-----------+--------------+---------------+
| id | id_profile2 | int_value | double_value | varchar_value |
+----+-------------+-----------+--------------+---------------+
| 1 | 1 | NULL | NULL | Aron |
| 2 | 2 | 17 | NULL | NULL |
| 3 | 1 | NULL | NULL | Vince |
| 4 | 2 | 27 | NULL | NULL |
| 5 | 1 | NULL | NULL | Elena |
| 6 | 2 | 78 | NULL | NULL |
| 7 | 3 | NULL | NULL | Banana |
| 8 | 4 | NULL | NULL | Yellow |
| 9 | 5 | NULL | 124.8 | NULL |
+----+-------------+-----------+--------------+---------------+
Here I have cleaner tables, but still a programmatic trick to implement to get everything in order.
The questions
Have anyone ever face this situation ?
What do you think of my 2 options ?
Is there a better solution, less tricky ?
Tx a lot!
Edit
Hi again,
My model had a bug : impossible to retrieve a "line" of information; i.e. the informations in the "values" table are not sortables.
After some wanredings around the EAV model, it showed not suitable because it's not designed to store datas, but specific infos.
Then I ended with this model :
Firt table 'labels' :
+----+------------+------+----------+
| id | profile_id | name | datatype |
+----+------------+------+----------+
| 1 | 1 | 1 | Nom |
| 2 | 1 | 1 | Age |
| 3 | 2 | 2 | Fruit |
| 4 | 2 | 2 | Couleur |
| 5 | 2 | 2 | Poids |
+----+------------+------+----------+
Then a very simple 'nodes' talbe, just to keep track of the lines of infos :
+----+------------+
| id | profile_id |
+----+------------+
| 1 | 1 |
| 2 | 1 |
| 3 | 2 |
| 4 | 2 |
+----+------------+
and a set of tables corresponding to different datatypes :
+----+---------+----------+--------+
| id | node_id | label_id | value |
+----+---------+----------+--------+
| 1 | 1 | 1 | John |
| 2 | 2 | 1 | Doe |
| 3 | 3 | 3 | Orange |
| 4 | 3 | 4 | Orange |
| 5 | 4 | 3 | Banane |
| 6 | 4 | 4 | Jaune |
+----+---------+----------+--------+
With this model, queries are ok. Data input is a bit tricky but I will manage with a clean code.
Cheers
Take a look at EAV data models.
Option 3: make two different tables.
One table is obviously for people. The other is obviously for fruit. They should be in different tables.
Why not just have a user table with name and ID, the a userValues table that has key value pairs? that was John can have key "fruit" and value "mango, and another key "tires" and value "goodyear". Bob can have key "coin" and value "penny" and key "age" and value "42". Anyone can have any value they like and you have maximum flexibility. Speed won't be great, and you'll have to cast string to values, but it's always a tradeoff.
Cheers,
Daniel