Consider the following two table
Table A:
id int auto_increment
with 2 rows of data.
id
1
2
Table B:
id auto_increment
aid reference to A.id
with 3 rows of data
id aid
1 1
2 2
3 2
If now the table A has been inserted 2 rows to
Table A:
id
1
2
3
4
So, how to write the insert statement so that it can insert to table B as result
Table B:
id aid
1 1
2 2
3 2
4 3
5 4
6 4
7 5
8 6
9 6
The question is for study only. I know there are many ways to do it, but I am just wondering if it can be done by using sql or just in mysql?
UPDATE
Sorry, the question since to be unclear. Let me state it in clear.
The data in table B has relation to table A. B.aid = A.id
The new data in table A, which is A.id, are in sequence, also has relation to the first two id. That means 1 and 3 with the same meaning, 2 and 4 also.
In the insertion of table B, it should consider both 1. and 2. That means, since with one aid=1 and two aid=2, then the data that needs to insert into table B is one aid=3, two aid=4, one aid=5 and two aid=6.
The question: This can be done easily with programming, however, I just wondering can 3. be done in a insert statement with out programming in Mysql?
Assuming you are inserting the ID(s) into Table A,
INSERT INTO [Table B](aid) VALUES ([THE ID])
Where this will insert the specified ID, in the aid column in Table B.
Otherwise if you want to match up the values you can use NOT IN to detect values that are not like, then you must insert these values,
This will select all IDs that do not exist in Table B:
SELECT id
FROM [Table A]
WHERE [Table A].id Not In (SELECT aid FROM [Table B])
...then later (depending what you're using it in, PHP? Then fletch the data (should look something like this))...
while($row = mysqli_fetch_assoc(...))
{
INSERT INTO [Table B](aid) VALUES($row['aid'])
}
Related
I'm trying to write a SQL query to find the lowest available/unused ID from a column named internal that exists in two separate tables:
machines
machines_ignore
Data is processed from an external source, and we want to fetch data from all machines that are not in the machines_ignore table. The ignore table is just a manual table set up by us when we identify machines we don't want to analyze.
I've found scripts that work on a single table (like only the machines table), but as soon as I try to get it working when combining two tables.
Example
Table 1 (machines)
id
internal
1
1
2
2
3
3
4
5
5
6
Table 2 (machines_ignore)
internal
4
7
8
9
12
Expected result
Based on the example above, this query should output 10, 11, 13 etc.
Any ideas?
One solution is to combine the values from both tables then check if each value has next value in both tables using EXISTS:
SELECT x.internal + 1
FROM (
SELECT internal FROM machines
UNION
SELECT internal FROM machines_ignore
) AS x
WHERE NOT EXISTS (
SELECT 1 FROM machines WHERE internal = x.internal + 1
) AND NOT EXISTS (
SELECT 1 FROM machines_ignore WHERE internal = x.internal + 1
)
LIMIT 1
Suppose I have these records
ID 1: has attributes A,B,D
ID 2: has attributes B,C
ID 3: has attributes F
ID 4: has attributes C,G
.....(Attributes will not duplicate in the same record)
Total estimated number of records: ~180,000
Total number of attributes: 70, increasing
Example of queries I'm going to do:
SELECT * from table WHERE (has attribute B)
SELECT * from table WHERE (has attributes B & D)
SELECT * from table WHERE (has 2 attributes)
SELECT * from table WHERE (has >=3 attributes)
SELECT count(*) from table WHERE (has attribute B)
What is the best database architecture?
Design 1: Storing attributes as 1s & 0s
ID|A|B|C|D|E|F|...
1|1|1|0|1|0|0|...
2|0|1|1|0|0|0|...
3|0|0|0|0|0|1|...
Problems:
New columns needed to be added periodically when new attribute appears
Much redundant data (0s), as more than 80% of data has only 1 attribute, and less than 0.01% of records will have more than 8 attributes.
Design 2: Store attributes as a CSV string
ID|Attributes
1|A,B,D,
2|B,C,
3|F,
Problems:
Slow query when I do
SELECT * from table WHERE attributes LIKE '%B,%' AND attributes LIKE '%D,%'
Design 3: Each attribute has its own table storing record IDs
Table Attribute A
ID
1
4
5
...
Table Attribute B
ID
1
7
10
...
Table Attribute C
ID
2
8
9
...
Problems
Many tables
New tables needed to be added periodically
How to do SELECT * from table WHERE id (appears in exactly 3 tables)?
These are the designs I can think of, please propose any good architecture.
Actually, none of your designs are optimal (the third is the best), and I recommend a single junction table which relates ID valued to their attributes, e.g.
ID | attr
1 | A
1 | B
1 | D
2 | B
2 | C
3 | F
4 | C
4 | G
This is the most normalized approach. To see why this design is optimal, see how easy it is to find all IDs which have attribute B:
SELECT DISTINCT ID
FROM yourTable
WHERE attr = 'B';
It is also fairly straightforward to find all IDs having both attributes B and D:
SELECT ID
FROM yourTable
WHERE attr IN ('B', 'D')
GROUP BY ID
HAVING MIN(attr) <> MAX(attr);
Your first two suggestions would make it much harder to write these queries (give it a try), and in general it is bad practice to store CSV in database tables. Your third suggestion does store the relationships correctly, but it unnecessarily spreads out data across multiple tables.
A more general form of the above query which can easily be extended to any number of IDs is:
SELECT ID
FROM yourTable
WHERE attr IN ('B', 'D')
GROUP BY ID
HAVING COUNT(DISTINCT attr) = 2;
I have two tables with the exact same structure/columns. I need to combine them without duplicates based on the second column (title). First column is ID and these may have duplicates but should be ignored.
Example of database structure
id (primary key, auto increment), title (unique), description, link
Ex. Table 1
1 Bob thisisbob bob.com
2 Tom thisistom tom.com
3 Chad thisischad chad.com
Ex. Table 2
1 Chris thisischris chris.com
2 Chad thisischad chad.com
3 Dough thisisdough doug.com
What I need in Table 3
1 Bob thisisbob bob.com
2 Tom thisistom tom.com
3 Chad thisischad chad.com
4 Chris thisischris chris.com
5 Dough thisisdough doug.com
Both tables have about 5 million entries/rows each. I need the most efficient way possible to combine them.
It is a little hard to understand exactly what you want. Perhaps, though, this might be:
select *
from table1
union all
select *
from table2
where not exists (select 1 from table1 where table1.title = table2.title);
This will run faster with an index on table1(title).
EDIT:
If you want to insert them into a third table, you can do:
create table table3 as
select *
from table1
union all
select *
from table2
where not exists (select 1 from table1 where table1.title = table2.title);
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
i have two different database schemas
First Structure is :
table 1 : country_master
Column name: id(primary key) country_name
table 2: State_master
Column name: id(primary key) State_name Country_id(foreign key of country_master)
table 3: City_Master
Column name: id(primary key) city_name State_id(foreign key of State_master)
Second Structure is:
table 1 : Master_table
Column name: id(primary key) name
table 2 : Sub_master
Column name: id(primary key) name master_id(Foreign key of master Table) subid(id of Sub_master)
Record of first structure
table: Country_master
1 india
2 UK
3 USA
table:State_master
1 gujarat 1
2 MP 1
3 Up 1
table:City_master
1 ahmedabad 1
2 surat 1
Record of structure 2:
table:master_table
1 Country
2 City
3 State
table:master_table
1 india 1 0
2 UK 1 0
3 USA 1 0
4 Gujarat 3 1
5 MP 3 1
6 Up 3 1
7 ahmedabad 2 4
8 surat 2 4
now my question is what is best schema of my tables for performance:
The second structure gonna be create more issue regarding performance point of view.
As the child table have all references, it is difficult to maintain. Consider the scenario, where you need to mark for the "capital" of each state having the crores of data, then what would you do to add one more column into existing table and update each of one? No not obviously, instead the better job is to separate all the cities, states and countries in a separate table and use in query having joins, so join performes on primary key. And the most important is, these data not gonna be change often means these remains constant most of the times. These are called lookups, hence you need to separate in a table. The first structure is good in a first appearance because dataset is too small, as data increases, that gonna create problems, hence the better is to use the first structure.
You could probably achieve the same performance by adding the right indices on the tables.
For ex: if one if your queries is search for all states in a country you would need to create an index on the master and sub id of the sub table in the second structure.
I think your second table structure is not complete.here parentid can be non-clustered index,type can be non-clustered index.table variable is just example to show
Declare #t table (id int identity(1,1) primary key,names varchar(100)
,parentid int,[type] int)
--where [type] can be enum 1=country,2=states,3 city
insert into #t values ('india',null,1) ,('gujrat',1,2)
,('surat',2,3) ,('Bihar',1,2),('Pakistan',null,1)
;with CTE as
(
select * from #t where id=1
union all
select a.* from #t a inner join cte b on a.parentid=b.id
)
select * from cte
IMHO,Advantage is that if city is not mandatory.then in first table
structure you have to use left join. In second example whatever be the
requirement you can always use Inner join.Hence second structure is
fast.Also second is more flexible.Just one proc will do
.
Though let other comment .
I have searched quite a lot but haven´t found a solution to my problem. Now I hope someone can help me here.
I have two tables in an MySQL database and both tables have the columns Name and ArticleID
What I would like to do is to copy the content in the column Name from Table 1 to Table 2 where the ArticleID match. All the names should be separated by a comma in the column Name in Table 2.
In Table 1 there are for example 3 rows with the same content in the column Name but each row has a unique ArticleID. In 3 other rows there are a different Name but the ArticleID´s is the same as the first 3 rows.
Table 1
Name 1 - 1
Name 2 - 2
Name 3 - 3
Name 4 - 1
Name 5 - 2
Name 6 - 3
Table 2
1 - Name 1, Name 4
2 - Name 2, Name 5
3 - Name 3, Name 6
This would not normally be a problem for me, But now there are multiple rows with the same ArticleID and i can´t seem to figure it out by my self.
I hope you understand what I want :-)
Melker
INSERT INTO TABLE2(id, names)
SELECT ArticleID, GROUP_CONCAT(Name)
FROM TABLE1 GROUP BY ArticleID;
UPDATE
TABLE2
JOIN (SELECT ArticleID, GROUP_CONCAT(Name) AS Name FROM TABLE1 GROUP BY ArticleID) TABLE1
ON TABLE2.ArticleID = TABLE1.ArticleID
SET TABLE2.Name = TABLE1.Name
WHERE TABLE2.ArticleID = TABLE1.ArticleID
I actually had to use UPDATE and this worked