How to combine tables in access 2010 - ms-access

I am a newbie with access and I need some help.
I am trying to combine 2 tables in access.
Table 1:
ID First_Name Last_Name Gender
12345 John Doe F
22345 Jane Clin M
Table 2:
ID First_Name Last_Name Grade
12345 Curt Doe 2
12345 Carry Doe 3
12345 Sid Doe 1
22345 Mel Clin 7
How do I write the SQL in Access to display
ID First_Name Last_Name Gender Grade
12345 John Doe F
12345 Curt Doe M 2
12345 Carry Doe 3
12345 Sid Doe 1
22345 Jane Clin M
22345 Mel Clin 7
Thank you for your help.

Given what you've provided a union and two left joins should do the trick. Though this is a terrible database design or the sample data is bad.
Here's why
The ID's are the same for all users
it appears one has to join on First and last Name and we all know spelling errors and name changes become difficult to manage thus data entry errors cause us to get improper results.
Curt has a gender in your sample results yet none exists in sample data. Where did this value come from?
I'm assuming the ID's should be what relate records; but we have to join on ID, first, and last names to possibly get a unique record. What are the PKs on those tables without this knowledge our answers are pure guesses.
if we assume Table1's PK is ID, and Table2 ID is a Foreign key to table1 then we should just be able to join on ID; but the sample data doesn't reflect this. So what are the PK's and FK's on each table?
.
Given the sample data and desired results; my approach would be to union all the IDs and names from both tables into one set of data then outer join this data back to table1 and table2 to get the gender and grades. Ideally we'd just be joining on ID; but the sample data doesn't seem to indicate the ID being a primary/Foreign key for either table.
SELECT Der.ID, Der.First_name, Der.Last_name, T1.Gender, T2.Grade
FROM (SELECT ID, First_Name, Last_name
FROM table1
UNION
SELECT ID, First_Name, Last_name
FROM Table2) DER
LEFT JOIN Table1 T1
on T1.Id = Der.ID
and T1.First_name = Der.First_name
and T1.Last_name = Der.Last_name
LEFT JOIN table2 T2
on T2.Id = Der.ID
and T2.First_name = Der.First_name
and T2.Last_name = Der.Last_name
Why?
Because neither table contains a complete list of names you want in your results but combined they do; thus the need to derive a table with all names and IDs. The outer joins then allow us to get the gender and grades for the unioned set.
But before progressing further; i'd really look at the table design and understand the PK/FK relationships and ensure your data is accurate. It seems table 1 is a "persons" table whereas table2 is more of a grades for each class/grade/year table. This would be a 1:M relationship; and as such the ID of the persons table should be a FK to the "grades" table which should have it's on PK or composite key for class year person. and then you wouldn't have to have the names in the grades table.. unless you were concerned about tracking name changes for each grade/year/semester...

SELECT A.ID, A.First_Name, A.Last_Name, A.Gender, B.Grade
FROM TABLE_1 A
INNER JOIN TABLE_2 B
on A.ID=B.ID;
Did you make these tables or is this something you're stuck with? If we assume that the ID is the common item in these then you don't want to put First_Name and Last_Name in both tables. Just include the ID in both tables to make the link.
If you want to include all from TABLE_2 regardless of whether or not they exist in TABLE_2 then change INNER JOIN to LEFT OUTER JOIN.
EDIT
I see I made a mistake in assuming that TABLE_1 was a primary. I think what you actually want in this particular case would be a union.
SELECT U.ID, U.First_Name, U.Last_Name, U.Gender, U.Grade
FROM (SELECT ID, First_Name, Last_Name, Gender, '' AS Grade
FROM TABLE_1
UNION
SELECT ID, First_Name, Last_Name, '' AS Gender, Grade
FROM TABLE_2) U
HTH,
Mike

Related

How to get multiple columns data into the same cell with a SQL query?

I need get an sql result that gets multiple columns data from a table into a single cell for the result. How would be the query?
Let's suppose I have this 2 tables:
Table 1:
Name spec
--------------
James front
--------------
Henry front
--------------
Henry back
Table 2:
Name dir
--------------
James 123
--------------
Henry 456
And I want to get this result:
Result Table:
Name spec dir
-----------------------
James front 123
-----------------------
Henry front 456
back
-----------------------
You can try using group_concat() function
select a.name, group_concat(spec SEPARATOR ' '),dir
from table1 a inner join table2 b on a.name=b.name
group by a.name,dir
The Solution for that problem is calling a join. A join combines multiple tables into one using certain identifiers. In your problem the identifier is the name. An example solution would be:
select table1.name, table2.spec, table2.dir
from table1 inner join table2 on table1.name = table2.name
Example: GROUP_CONCAT is correct, but if you want spec column value print in new line then use '\n'
SELECT a.name, GROUP_CONCAT(spec SEPARATOR '\n'),dir
FROM table1 a INNER JOIN table2 b ON (a.name=b.name)
GROUP BY a.name,dir;

Joining tables using MySQL

Sorry for bad title, but I don't know what is should be.
I want to join two tables but the number of line should be same as table one.
Here are my tables
====Table 1=====
| Name | IdCardNo |
===============
| Peter | 1234 |
| Mary | 5678 |
===============
==========Table 2=========
| IdCardNo | phoneNo | Job |
=========================
|1234|11111111|Student|
|1234|11111111|Waiter|
|5678|22222222|Student|
=========================
Here is the result i want
Peter|1234|11111111|
Mary|5678|22222222|
However if i do SELECT NAME, PhoneNo FROM Table1 LEFT JOIN Table2 on Table1.IdCardNo=Table2.IdCardNo
I get this
Peter|1234|11111111|
Peter|1234|11111111|
Mary|5678|2222222|
I know I can do GROUP BY NAME but I don't think it is a good idea.
What query should I use?
I think SELECT DISTINCT... is the thing I want. Thank you!
Just use DISTINCT
The SELECT DISTINCT statement is used to return only distinct
(different) values.
Something like
SELECT DISTINCT NAME, PhoneNo
FROM Table1 LEFT JOIN
Table2 on Table1.IdCardNo=Table2.IdCardNo
Maybe you might want to reconsider the design of the tables. Unless a different (possible) number is required per instance of table2, you might want to store the number in table1?
Your expected result is ambiguous
Mary|5678|11111111|
I suppose should be
Mary|5678|22222222|
This could be achieved as
select
t1.Name,
t1.IdCardNo,
t2.phoneNo
from table1 t1
join table2 t2 on t1.IdCardNo = t2.IdCardNo
group by t1.Name,t1.IdCardNo,t2.phoneNo
SELECT distinct t1.NAME, t1.idCardNo, t2.PhoneNo FROM Table1 t1 LEFT JOIN Table2 t2 on t1.IdCardNo=t2.IdCardNo
Distinct will skip identical rows in the result set!
'Select distinct' will only populate the joined table with unique values. Try that and let me know.

MySQL, summing certain rows from a hash table, using results from a subquery

I'm trying to sum certain rows from a hash table using two elements: a select group of IDs and a particular key.
Here's the setup:
Table 1:
ID KEY VALUE
1 name John Doe
1 amount 10
2 name Jane Doe
2 amount 15
3 name Mike Lowry
3 amount 5
Table 2:
ORDERID TYPE TRANSACTIONID
1001 Purchase 1
1002 Donation 2
1003 Purchase 3
I'm trying to get a sum of all the amounts where the type is "Purchase." Here's the query I'm using:
SELECT SUM(Table1.value) as balance
FROM Table1
LEFT JOIN (SELECT Table2.TRANSACTIONID as TID FROM Table2 WHERE Table2.TYPE = "Purchase" ) as ids
ON Table1.ID = ids.TID
WHERE Table1.key = "amount"
Tweaking that, I've managed to get 0 and the total of all the rows, but not just the one result. Ideas?
The problem is that your query makes an outer join between Table1 and Table2, such that all records of Table1 are preserved irrespective of whether a matching record is found from Table2. Learn about SQL joins.
You want to make an inner join instead:
SELECT SUM(VALUE)
FROM Table1 JOIN Table2 ON Table1.ID = Table2.TRANSACTIONID
WHERE Table1.KEY = 'amount' AND Table2.TYPE = 'Purchase'
See it on sqlfiddle.

how to prevent duplicated rows in access 2007

now i am working with three tables,A,B and C:
A table structure:
ID,
Name,
Age
B table structure:
ID,
A.ID-> foreign key,
Hospital Name
C table structure:
ID,
A.ID->foreign key,
Drug Name
so the relation between A and B is one to many and also the same with A and C
when i make any query to find how many persons in my database i found duplicated rows
actually its not duplicated but it has for example 2 rows with the child table like: the one person has 2 records in table B so the result doesn't reflect the actual number of matched record because its linked with child tables .
Question is : how to prevent duplication in case like that?
You can use Distinct or a subquery.
SELECT DISTINCT a.ID, a.Name
FROM a
INNER JOIN b
ON a.ID = b.aID
WHERE b.Hospital = 123
Or
WHERE b.Hospital IN ( 123, 456 )
Also
SELECT a.ID, a.Name
FROM a
INNER JOIN (SELECT aID, Hospital FROM b) x
ON a.ID = x.aID
WHERE x.Hospital - 123
And
SELECT a.ID, a.Name
FROM a
WHERE a.ID
IN ((SELECT aID FROM b WHERE Hospital = 123))

How do I write a SQL query to detect duplicate primary keys?

Suppose I want to alter the table so that my primary keys are as follows
user_id , round , tournament_id
Currently there are duplicates that I need to clean up. What is the query to find all duplicates?
This is for MySQL and I would like to see duplicate rows
Technically, you don't need such a query; any RDBMS worth its salt will not allow the insertion of a row which would produce a duplicate primary key in the table. Such a thing violates the very definition of a primary key.
However, if you are looking to write a query to find duplicates of these groups of columns before applying a primary key to the table that consists of these columns, then this is what you'd want:
select
t.user_id, t.round, t.tournament_id
from
table as t
group by
t.user_id, t.round, t.tournament_id
having
count(*) > 1
The above will only give you the combination of columns that have more than one row for that combination, if you want to see all of the columns in the rows, then you would do the following:
select
o.*
from
table as o
inner join (
select
t.user_id, t.round, t.tournament_id
from
table as t
group by
t.user_id, t.round, t.tournament_id
having
count(*) > 1
) as t on
t.user_id = o.user_id and
t.round = o.round and
t.tournament_id = o.tournament_id
Note that you could also create a temporary table and join on that if you need to use the results multiple times.
SELECT name, COUNT(*) AS counter
FROM customers
GROUP BY name
HAVING COUNT (*) > 1
That's what you are looking for.
In table:
ID NAME email
-- ---- -----
1 John Doe john#teratrax.com
2 Mark Smith marks#teratrax.com
3 John Doe jdoe#company.com
will return
name counter
---- -------
John Doe 2
Assuming you either have a table with those three columns, or that you can make and populate a table with those three columns, this query will show the duplicates.
select user_id, round, tournament_id
from yourtable
group by user_id, round, tournament_id
having count(*) > 1
This query selects all rows from the customers table that have a duplicate name but also shows the email of each duplicate.
SELECT c.name, c.email FROM customers c, customers d
WHERE c.name = d.name
GROUP BY c.name, c.email
HAVING COUNT(*) > 1
The downside of this is that you have to list all the columns you want to output twice, once in the SELECT and once in the GROUP BY clause. The other approach is to use a subquery or join to filter the table against the list of known duplicate keys.