How to assign a key for duplicate rows - mysql

id salary address
101 $400 NY
101 $200 NY
102 $102 TX
102 $127 TX
102 $391 TX
Now how to assign key for every repeating row based on id column
id salary address key
101 $400 NY 1
101 $200 NY 2
102 $102 TX 1
102 $127 TX 2
102 $391 TX 3

If I understood correctly, you want to get an ID based on the id occurrences, so you can define both as a unique key, right?
First, you can use SQL COUNT to find the number of times that an id appears on the table, then increment the result to get your id. Example in pseudocode:
sqlresult = sqlquery( COUNT(*) FROM `your_table` WHERE id = "wanted_id";);
key = sqlresult++;
Then you can define a composite key by following this post:
How can I define a composite primary key in SQL?
Sorry for not being more detailed, but right now I don't have much time, if you need I can help you better later on today.
Hope I could help.

Related

"Merging" ids together in SQL

I have a table cities like this:
id
city
1
Vancouver
2
Calgary
3
Calgry
And multiple other tables which reference cities, something like this (just some example numbers).
id
city_id
year
population
1
1
2000
100000
2
1
2001
130000
3
3
2000
70000
4
3
2001
85000
5
2
2002
95000
I want to merge/consolidate city id 3 into id 2, so change every occurrence of id 3 across all tables to 2, and then delete city id 3. Is there a clean way of doing this?
Something like ON UPDATE CASCADE would work perfectly but I can't have duplicate primary ids. At the very least I could loop through the foreign keys and run a query on every table but I'm not sure if there's a more idiomatic way.
ON UPDATE CASCADE causes duplicate PK. To avoid that, we can use ON DELETE SET NULL which nullify all the city_id with a value 3 in other tables once we delete the city_id 3 from the cities table, but then you would still have to change the city_id from null to 2 in the said tables. This is not fundamentally different to change those city_id with a value 3 to 2 for the other tables , then just delete id 3 from the cities table. If you feel reluctant to manually do that or if there are too many tables to handle, then use a procedure. Make a list of table , declare a cursor for the list and loop through the list to get each table name and use a prepared statement to do the UPDATE.

Create new column storing average of rows from another column in MySQL

I am trying to create a new column that has stores the 'Average weight of the field'. For example, the answer for RaceID = 123 would be 54.5. The RaceID's are not organised from smaller to largest and are displayed randomly like the example below.
RaceID
Weight
No. Starters
123
56
2
124
58
2
123
53
2
125
60
2
125
51
2
124
62
2
Try below query, It will display current table data along with average column :
select t.*,
avg(Weight) over(partition by raceID order by raceID ) avg_raceID
from table t;
SELECT RaceID, AVG(Weight) AS val_1
FROM dataset_name
GROUP BY RaceID;
By using above code we can get the average value of weights for every unique RaceID. Check the below image for better understanding.
https://i.stack.imgur.com/kMA68.png
Let me know if there are any modifications or error.

SQL Select, replace ID with table column from foreign key

Lets say I have two tables, and in this example, the fish table has Place as a foreign key. In a select statement, how can I get the average weight per place, but instead of showing the id, it shows either the name of the place or the country that has the same id.
Fish
ID Type Weigth Place
1 Cod 300 1
2 Pike 600 2
3 Pike 1000 2
4 Salmon 800 1
Place
ID Name Country
1 NY USA
2 London UK
3 Oslo Norway
I can only figure out how to get average weight per place and return the id, but not the name or country of the place. I think I need to use join of some sort, but cant figure out how.
Thanks in advance

link slowly changing dimension with fact table using another table

I have one slowly changing dimension type 2, one fact table and another lookup table that links the two. isCurrent field in the dimension will be updated based on loadDate. I am trying to create a logic to load the second column of the table that links the fact and dimension but not having any luck yet. Here is what I am trying to achieve. The linking table is supposed to hold all IDs in column 1 and the corresponding LinkedID in column 2. And if the isCurrent flag changes, LinkedID column should update to the ID with isCurrent = Y. btw: ID is not employeeId, it is just a reference number that ties the dimension with the fact.
Here is an example of what the Link table should look like:
Record 1:
Dimension Table
ID Name State isCurrent
101 Alex TX Y
Link table:
ID LinkedID
101 101
Record 2:
Dimension table:
ID Name State isCurrent
101 Alex TX N
102 Alex CA Y
Link table
ID LinkedID
101 102
102 102

RDBMS Schema design - should I separate the tables or not in order to capture new attribute?

I have these two tables now:
1)
Models
id (PK) desc ...
2)
Model_Hierarchy
parent_id (PK) child_id (PK) qty
This represents a basic structure of production assembly. For example Model id = 001, desc = "shoeA" can consist of 2 other models:
1) model id = 002, desc = "upperA"
2) model id = 003, desc = "soleA"
and the relationship would be simply represented in the hierarchy table as follows:
Model_Hierarchy
parent_id (PK) child_id (PK) qty
001 002 1
001 003 1
So in my application it would look like:
name qty
shoeA---
-upperA 1
-soleA 1
This works for now. However, now I found out that for some specific model relationships I also have to catch attribute size. For example, I have a model cuttingKniveA and I would like to capture something like:
name size area (cm^2)
cuttingKniveA 35 12.4
36 12.9
37 13.6
38 13.6 *note
. .
. .
HOWEVER *note: I must be able to capture the fact that for some sizes, same knive can be used. So for example for size 38 the same knive is used as for size 37! This is the part that I struggle with and I'm not sure how to represent it in my RDBMS.
There are several ways to do this and I'm not sure which one to pick (the most efficient / clear for future development).
First approach:
In Models table:
id(PK) desc
1 cuttingKniveA
2 35
3 36
4 37
In Model_Hierarchy table:
parent_id (PK) child_id (PK) qty
1 2 12.4
1 3 12.9
1 4 13.6
How would I catch the fact that size 38 uses the knive with size 37? Ie. model_id 4.
Second approach:
In Models table:
id(PK) desc
1 cuttingKniveA
2 ""
3 ""
4 ""
In Model_Hierarchy table:
extend by adding size attribute.
parent_id (PK) child_id (PK) size qty
1 2 35 12.4
1 3 36 12.9
1 4 37 13.6
Here it might be easier to capture that size 38 uses same knive, yet I don't like such solution. Ie:
parent_id (PK) child_id (PK) size qty
1 4 38 13.6
There are 2 big problems here:
1) Keeping qty consistent (ie. even though size 37 and 38 are the same child_id of 4, they are 2 records and so a change to 1 must change the qty of the other too.
2) As of now it validates the primary key condition, ie. unique parent_id, child_id pairing. This complicates things as capturing this relation is a small subset of all relations shown in Model_Hierarchy and so I could add size attribute for this small subset, but I would rather not make a major change to the table such as changing the PK.
Third approach:
Create a new table to capture the size relationship, ie.
parent_id (PK) child_id (PK) size (PK) qty
1 2 35 12.4
1 3 36 12.9
1 4 37 13.6
1 4 38 13.6
There is two problems I see:
1) Same problem with keeping the qty consistent as in the Second approach, ie. if 13.6 changes it should change in both records.
2) Now I have a new table that captures extremely similar structure as a table I already have (ie. parent - child - qty).
Is there some other easier way to do it that I'm not seeing?
If I understand it properly, knife size is a property of the knife, not a property of the hierarchy - so IMO it belongs in the part table that describes knife. Size 37 and size 38 are 2 different knife codes, I think. In the hierarchy table, you need some logic that defines alternate parts, to show that in some particular assembly, either knife could be used. You might try a dummy part, with the definition of that part showing the 2 optional sizes that could be used. In any case, there's more than the data structure involved - you need some logic that allows for OR conditions in the hierarchy table, rather than just the AND condition that is normally used.
Having some trouble understanding your explanation. Hopefully I've included everything you need and it's understandable if a little long
Would this design work:
Domains
(note: Domains are basically the data types you'll be using - fields created on the same domain can be used to join tables)
IdentifierOfShoeModel - integer
IdentifierOfSubModel - integer
IdentifierOfKnife - integer
IdentifierOfShoeSize - integer
DescriptionOfShoeModel - string
DescriptionOfSubModel - string
DescriptionOfKnife - string
ShoeSize - double
ShoeArea - double
SubModelQty - integer
Table: Model
ID - IdentifierOfShoeModel
Desc - DescriptionOfShoeModel
Primary Key ID
Table: Knife
ID - IdentifierOfKnife
Desc - DescriptionOfKnife
Primary Key ID
Table: SubModel
ID - IdentifierOfSubModel
ModelID - IdentifierOfShoeModel
Desc - DescriptionOfSubModel
Primary Key ID
Foreign Key ModelID references Model
Table: Size
ID - IdentifierOfShoeSize
KnifeID - IdentifierOfKnife
Size - ShoeSize
Area - ShoeArea
Primary Key ID
Foreign Key KnifeID references Knife
Table: Cutting
ShoeID - IdentifierOfShoeModel
SizeID - IdentifierOfShoeSize
Primary Key (ShoeID, SizeID)
Foreign Key ShoeID references Model
Foreign Key SizeID references Size
With these entries in the tables:
Model
ID Desc
1 ShoeA
Knife
ID Desc
1 cuttingKnifeA
SubModel
ID ModelID Desc
1 1 upperA
2 1 soleA
Size
ID KnifeID Size Area
1 1 35 12.4
2 1 36 12.9
3 1 37 13.6
4 1 38 13.6
Cutting
ShoeID SizeID
1 1
Use this query to get the results in the bottom table:
SELECT Model.Desc,
SubModel.Desc,
Knife.Desc,
Size.Size,
Size.Area
FROM (((
Cutting INNER JOIN Model ON Cutting.ShoeID = Model.ID)
INNER JOIN [Size] ON Cutting.SizeID = Size.ID)
INNER JOIN Knife ON Size.KnifeID = Knife.ID)
INNER JOIN SubModel ON Model.ID = SubModel.ModelID
ORDER BY Model.Desc,
Knife.Desc
Model.Desc SubModel.Desc Knife.Desc Size Area
ShoeA soleA cuttingKnifeA 38 13.6
ShoeA upperA cuttingKnifeA 38 13.6
ShoeA soleA cuttingKnifeA 35 12.4
ShoeA upperA cuttingKnifeA 35 12.4