I have 3 tables for data of divisions, districts and police_stations table. The table data are dependent like
divisions
- districts
-- police_stations
Table format are
divisions
id
name
districts
id
division_id
name
police_stations
id
division_id
district_id
name
Can I design just one table with all of my tables data with current table dependency? If I can, how will be the traversing process?
To group multiple tables together, you should use JOINS. This is a better database practice than creating new tables.
The INNER JOIN keyword selects all rows from both tables as long as there is a match between the columns in both tables.
SELECT *
FROM divisions divis
INNER JOIN districts dis
ON dis.division_id = divis.id
INNER JOIN police_stations pol
ON pol.district_id = dis.id
Note: Apparently the DIV keyword is reserved in mysql, so you you have to use something else to identify divisions.
If you insist on creating a new table with this data, you can use the CREATE TABLE AS recipe.
In order to do this though, we need to modify our original schema. New tables cannot have duplicate names, so we have to change the original tables to all have unique columns.
For example name becomes district_name.
CREATE TABLE combined AS (
SELECT divis.id, divis.division_name, dis.district_name, pol.police_name
FROM divisions divis
LEFT JOIN districts dis
ON divis.id = dis.division_id
LEFT JOIN police_stations pol
ON pol.district_id = dis.id
);
Here is a fiddle to demonstrate it
http://sqlfiddle.com/#!9/7ec3b/1/0
This is really bad database design though. My first solution is recommended
Using a single table: There would be an id for uniquely identifying each row; it would be the PRIMARY KEY. There would be a parent_id to say which other row is its 'parent' (division is parent of district, etc).
The JOIN becomes a self join.
SELECT ...
FROM tbl AS division
JOIN tbl AS district ON division.id = district.parent_id
JOIN tbl AS station ON district.id = station.parent_id
WHERE ...
Be sure to 'qualify' each field in the SELECT and WHERE with the appropriate 'alias'; example: division.name.
This design pattern works for most 'hierarchical' structures of arbitrary depth. Yours is exactly 3 levels deep, so it is somewhat simpler.
Note that the parent_id would be 0 for any "district" rows. And it would be useful to have INDEX(parent_id).
Hopefully it solves your problem
SELECT * from divisions d
join police_stations ps on d.id=ps.division_id
join districts dist on ps.district_id =dist.id;
Related
I am still a beginner and i searched in google ,read w3schools and couldn't get how to do it the following thing.
i want to create view from the info in cases field
AS you saw these are the info inside the tables (names,depart,idcards)
this the table i want to get the data from i made all the column start with id_* as foreign key for the PK in the previous tables
note:id_case is the PK of the table, id_dep is for department,id name is for name,id_complaint
This is just a bunch of joins:
CREATE VIEW viewname AS
SELECT *
FROM cases AS c
JOIN names AS n ON c.id_name = n.id
JOIN depart AS d ON c.id_dep = d.id
JOIN complaint AS cm ON c.id_complaint = cm.id
...
Note that if there are any column names that are the same among any of the tables, you'll need to list them explicitly in the SELECT list and assign distinct aliases to them. See MySQL JOIN tables with duplicate column names
I am trying to join two tables which are only related on another table (3rd table) and the identity of the two tables are foreign key of the 3rd table. Please refer to the image below so that I can fully describe what I am trying to achieve.
Relationship specs:
Actual.Id = Actual x Budget.Id
Budget.Id = Actual x Budget.Id
Budget.DateField = Actuals x Budget.DateField
And the last relationship: They are assigned as same data on Actual x
Budget.ColA
Is this achievable or should I change my database schema?
For your ActualXBudget table, don't use a single field for ID's from BOTH actual and budget. Use two columns, one for budgetID and one for ActualID. That way, a single row from ActualXBudget will be linked to both budget and Actual.
With your design, the DB has no idea that Budget ID 4 = Actual ID 1.
With Actual ID and Budget ID in the ActualXBudget Table, you can do simple joins to both tables and pull out attached records, like
SELECT Actual.ColA,Actual.ColB,Budget.ColB,Budget.ColC FROM
(Actual INNER JOIN ActualXBudget ON Actual.ID = ActualXBudget.ActualID)
INNER JOIN Budget ON Budget.ID = ActualXBudget.BudgetID
Edit: With your setup you could do
SELECT Actual.ColA,Actual.ColB,Budget.ColB,Budget.ColC FROM
(Actual INNER JOIN ActualXBudget ON Actual.ID = ActualXBudget.ID )
INNER JOIN Budget ON Budget.DateField = ActualXBudget.DateField
but don't do that.
I have a MySQL db that has 2 tables that have related information that I need to merge to 1 table.
Gallery has an itemid that relates to rbitems Id. Both tables gallery and rbitems have different column names but both have unique data. I want to merge the two tables based on the Id and itemid columns.
So how do I merge 2 different tables into 1 based on 1 column having unique values. I'd like to just append the other tables to the merge.
You can use JOIN to solve your problem.
SELECT a.*, b.*
FROM galley a INNER JOIN rbitems b
on a.itemid = b.id
CREATE TABLE new_table
AS (SELECT g.itemid, g.a, g.b, g.c, r.x, r.y, r.z
FROM gallery g INNER JOIN rbitems r
ON g.itemid = r.id
);
You may wish to add "AS name" to the members of the select clause.
If you have elements of the original tables that are not represented in the other table you should look into RIGHT, LEFT, or OUTER JOIN instead of INNER.
This assumes that the itemid and id columns are unique--a given itemid/id does not exist multiple times in the same table.
I have a query that requires what I think is a complicated JOIN. I have three tables that are sort of "children" of each other. The top table is "clan_members". The next is "roster_members" which gets the clan_member id. The bottom one is "match_players" which gets the roster_members id. I wrote a loop that takes me through all of the results in the clan_members table. What I want to do is find out how many matches that clan member has played in. Here's the layouts of the three tables:
[clan_members]
-id
- member_id
-join_date
[roster_members]
- id
- clan_member_id
- title
[match_players]
- id
- roster_member_id
- match_id
I have never done a JOIN with three different tables before and I have no idea what order to do them in. I would greatly appreciate it if someone could write me a query!
This query will get you the number of matches that clan member with id 123 has participated in:
select count(*) as match_count
from clan_members c, roster_members r, match_players m
where c.member_id = r.clan_member_id
and r.id = m.roster_member_id
and c.id = 123
On a side note, it would be good practice to name your columns consistently. For example, all columns that have the clan_member_id should be named the same. In the clan_members table its called id but in the roster_members table its called clan_member_id. Just makes it easier to understand how the tables join together.
SELECT DISTINCT match_id
FROM clan_members
INNER JOIN roster_members
ON clan_members.id = roster_members.clan_member_id
INNER JOIN match_players
ON roster_members.id = match_players.roster_member_id;
will get you the # of unique match_ids when all three tables are joined.
I have 2 tables. One (domains) has domain ids, and domain names (dom_id, dom_url).
the other contains actual data, 2 of which columns require a TO and FROM domain names. So I have 2 columns rev_dom_from and rev_dom_for, both of which store the domain name id, from the domains table.
Simple.
Now I need to actually display both domain names on the webpage. I know how to display one or the other, via the LEFT JOIN domains ON reviews.rev_dom_for = domains.dom_url query, and then you echo out the dom_url, which would echo out the domain name in the rev_dom_for column.
But how would I make it echo out the 2nd domain name, in the dom_rev_from column?
you'd use another join, something along these lines:
SELECT toD.dom_url AS ToURL,
fromD.dom_url AS FromUrl,
rvw.*
FROM reviews AS rvw
LEFT JOIN domain AS toD
ON toD.Dom_ID = rvw.rev_dom_for
LEFT JOIN domain AS fromD
ON fromD.Dom_ID = rvw.rev_dom_from
EDIT:
All you're doing is joining in the table multiple times. Look at the query in the post: it selects the values from the Reviews tables (aliased as rvw), that table provides you 2 references to the Domain table (a FOR and a FROM).
At this point it's a simple matter to left join the Domain table to the Reviews table. Once (aliased as toD) for the FOR, and a second time (aliased as fromD) for the FROM.
Then in the SELECT list, you will select the DOM_URL fields from both LEFT JOINS of the DOMAIN table, referencing them by the table alias for each joined in reference to the Domains table, and alias them as the ToURL and FromUrl.
For more info about aliasing in SQL, read here.
Given the following tables..
Domain Table
dom_id | dom_url
Review Table
rev_id | rev_dom_from | rev_dom_for
Try this sql... (It's pretty much the same thing that Stephen Wrighton wrote above)
The trick is that you are basically selecting from the domain table twice in the same query and joining the results.
Select d1.dom_url, d2.dom_id from
review r, domain d1, domain d2
where d1.dom_id = r.rev_dom_from
and d2.dom_id = r.rev_dom_for
If you are still stuck, please be more specific with exactly it is that you don't understand.
Read this and try, this will help you:
Table1
column11,column12,column13,column14
Table2
column21,column22,column23,column24
SELECT table1.column11,table1.column12,table2asnew1.column21,table2asnew2.column21
FROM table1 INNER JOIN table2 AS table2asnew1 ON table1.column11=table2asnew1.column21 INNER TABLE table2 as table2asnew2 ON table1.column12=table2asnew2.column22
table2asnew1 is an instance of table 2 which is matched by table1.column11=table2asnew1.column21
and
table2asnew2 is another instance of table 2 which is matched by table1.column12=table2asnew2.column22