Multiple to Multiple, Junction Tables, Newbie on Database Structure - database

Please feel free to comment on this as I am new and very confused on how to structure this.
I want to create a database of people with interests. I want to record their interests and then see what people have common interests and display them.
I have 3 tables: Person, Interest, InterestType
Person is a table of people
Interest is an interest that a person can have.
InterestType is the name of the interest, say Skiing or Biking. (I separated it because I want all person to use a common typeset of interests)
My setup is as follow:
personTable: id, name, interestID
interestTable: id, interestType, personID
interestType: id, name
How do I get the list of people with the same interest?

I have made a simple model in Access, but you should be able to "translate" this to SQLite without too many problems.
Given:
PersonTable
personId Name
1 Paolo
2 Carla
3 Angelo
4 Franco
5 John
6 Lisa
InterestType
interestId Name
1 Calligraphy
2 Karate
3 Chess
4 Movies
5 Hiking
InterestTable
interestId personId
1 1
2 1
3 1
2 2
3 2
4 2
1 3
2 3
1 5
A simple query sorted by Interest Name and then by Person Name should do the trick:
SELECT interestType.Name, personTable.Name
FROM personTable INNER JOIN
(interestType INNER JOIN interestTable ON
interestType.interestId=interestTable.interestId)
ON personTable.personId=interestTable.personId
ORDER BY 1, 2;
will return:
interestType.Name personTable.Name
Calligraphy Angelo
Calligraphy John
Calligraphy Paolo
Chess Carla
Chess Paolo
Karate Angelo
Karate Carla
Karate Paolo
Movies Carla
If you want to look for a specific interest, just add a where clause:
SELECT interestType.Name, personTable.Name
FROM personTable INNER JOIN
(interestType INNER JOIN interestTable ON interestType.interestId=interestTable.interestId)
ON personTable.personId=interestTable.personId
WHERE interestType.Name="Karate"
ORDER BY 1, 2;
interestType.Name personTable.Name
Karate Angelo
Karate Carla
Karate Paolo

Try this..
SELECT * FROM personTable pt
INNER JOIN interestTable it
ON pt.id = it.id
WHERE it.interestType = "theInterestType";

Related

SELECT INTO returning multiple records when it should return 1

EDIT:
I've since edited the query using JOINS instead of a WHERE clause in light
of suggested comments. I was using a WHERE clause instead of JOIN because I
couldn't get it to work across three tables but have figured it out. I've
also inserted SELECT DISTINCT because it does solve the problem.
Thanks #MichaelEvanchik, and #SeanLange for the help. Im still learning and hope I don't frustrate you guys too much.
I've looked over many of the multiple return threads and don't seem to find an answer that helps me.
I have 4 tables.
table1
ID Cat1_Name1 Cat1_Name2 Cat2_Name1 Cat2_Name2
12 Mike Mike George Mike
13 Jen Jen Amy Amy
14 Jeff Jen Mike Ben
15 Jeff Jeff Fred Tom
16 George Jen Luke Amy
table2
ID Cat1_Name1 Cat1_Name2 Cat2_Name1 Cat2_Name2
25 Mike Mike Jen George
table3
Name Cat1_Value Cat2_Value
Mike 6.5 20.25
Jen 10.2 0.5
Jeff 11.5 1.5
George 8.0 27.1
table4
Name Cat1_Value Cat2_Value
Mike 7.8 20.0
Jen 6.0 13.0
Jeff 13.2 5.0
George 8.0 1.2
Before anyone asks, the set of names in table2 must stay separate from table1. It isn’t duplicate information, but a SINGLE UNKNOWN SET that will be compared to every record in table1, which can contain millions of known sets (i.e.; no ID’s in table1 will ever match the ID in table2). If you look at the tables you can see that the set of names CAN match between table1 and table2 but do not have to. For example, the names for cat1 match between tables 1 and 2 for ID 12 and 25 (all 4 are Mike) but doesn't match any between IDs 13,14,15,16 and 25 (only the two in 25 are Mike). While at cat2, ID 12 and 25 match partially (i.e., the names in cat2 between tables 1 and 2 contain the name George but do not match in the second name). Here I show two categories. There will be upwards of 30 categories of names for one record but for now, I am focusing on 1 to solve this particular problem. Cat1_Name1, Cat1_Name2. I will worry about aggregating the different categories and logical name combinations with JOINs and UNIONs and answer my other question later….hopefully.
I want to create a new table that returns the ID from table1, with the associated value for each category depending on how many names match in the category. For example, since cat1_name 1 and 2 in table1 are mike,mike AND cat1_name 1 and 2 in table2 are mike,mike, return the ID from table 1 (12) and value in table 3 for cat1 (6.5). Different sets of matching names would return values from different tables (i.e.; the partially matching set in cat2 between 12 and 25 might return the value from table4 etc). I asked a similar question about this previously, here but the problem was different:
Returning Results from different tables depending on conditions from two other tables
I have a partial answer for it but now have a different problem. I plan on posting an answer to the first, once I figure out this problem (hopefully with a little help  ).
Here’s my query:
SELECT DISTINCT dbo.table1.ID, dbo.table3.Cat1_Value
INTO Cat1Table
FROM dbo.table2
INNER JOIN dbo.table3 ON (dbo.table1.Cat1_Name1 = dbo.table3.Name ) AND
(dbo.table1.Cat1_Name2 = dbo.table3.Name )
INNER JOIN dbo.table1 ON (dbo.table2.Cat2_Name1 = dbo.table3.Name ) AND
(dbo.table2.Cat2_Name2 = dbo.table3.Name )
Result table that I want:
Cat1Table
ID Cat1_Value
12 6.5
What I’m getting:
Cat1Table
ID Cat1_Value
12 6.5
12 6.5
Why am I getting a duplicate? Is it my logic or am I missing something else more simple? If I use SELECT DISTINCT it gives me the correct return but I'm thinking there might be a more efficient way because this will be expanded to millions of records. Wouldn't SELECT DISTINCT slow everything down?

SQL Server 2008 Perform a draw between 2 tables

I have 2 tables on SQL Server 2008, each one has a single column and the same rows count number:
USERS OPERATION
Name Operation
----------- -----------
John W383
William R823
Karen X933
Peter M954
Alex S744
I need to perform every week a random draw between the 2 tables to get something like the follow and save it into a 3rd. table:
DRAW_RESULT:
Name Operation_Assigned Week_Number
----------------------------------------------
Peter M954 2
William W383 2
John S744 2
Alex X933 2
Karen R823 2
Name Operation_Assigned Week_Number
----------------------------------------------
William R823 3
Alex M954 3
Karen X933 3
John S744 3
Peter W383 3
How can I do this using T-SQL?
If I understood correctly what you're doing, something like this should work:
select name, operation from (
select
row_number() over (order by (select null)) as RN,
name
from
users
) U join (
select
row_number() over (order by newid()) as RN,
operation
from
operation
) O on U.RN = O.RN
Edit: row_number with newid() works, so removed the extra derived table.
Here's also SQL Fiddle to test this.

How do I get multiple values from a table in SQLite?

I have three tables:
authors
idname
1 Albert
2Bobby
3 Carl
4 Dan
authors_musicals
rowidauthor_idmusical_id
1 1 1
2 2 1
3 1 2
4 1 3
musicals
id title year
1 Brigadoon 1947
2My Fair Lady1956
3 Oklahoma! 1943
4 Camelot 1960
I need to get all the titles belonging to Albert (his id (1) from authors corresponds to musical_id (1, 2, 3) in authors_musicals which each correspond to title (Brigadoon, My Fair Lady, Oklahoma!) in musicals). I thought the following would work:
SELECT title FROM musicals WHERE id=(SELECT musical_id FROM authors_musicals WHERE author_id=(SELECT id FROM authors WHERE name="Albert"));
This only gives me the first listing. How can I get all three and since these tables are linked, is there a simpler way of getting what I want?
JOIN the tables:
SELECT musicals.title
FROM musicals
JOIN authors_musicals ON (musicals.id = authors_musicals.musical_id)
JOIN authors ON (authors.id = authors_musicals.author_id)
WHERE authors.name = "Albert"
I don't use SQLite but I would assume that it's basically the same as using SQL for any other database. When you use SomeColumn = SomeValue you can only have one value on the right-hand side. Even if your subqueries produce multiple results, only the first will be used because you're using =.
You should be able to keep your current SQL structure and make it work by replacing = with IN, assuming that SQLite supports that operator. Then you'll be comparing to all the results instead of just one.
That said, I don't think that you should be using subqueries at all. It seems more appropriate to be using joins there. Again, there might be some small syntax difference but something like this should work:
SELECT title FROM musicals INNER JOIN authors_musicals
ON musicals.musical_id = authors_musicals.musical_id INNER JOIN authors
ON authors.author_id = authors_musicals.author_id
WHERE authors.name = 'Albert'
Combine the info between tables and get what you need:
SELECT title
FROM authors, authors_musicals, musicals
WHERE name="Albert" and authors.id=authors_musicals.author_id and musical_id = musicals.id;

SQL Server : query two columns from table1 in one row on result

I have the following tables:
Manufacturer: Model range:
IDManufacturer Manufacturer IDModelRange IDManufacturer ModelRange
1 Mercedes 1 1 Benz
2 Audi 2 1 E-Klasse
3 2 TT
4 2 A4
I would like to query the data from both tables and the result to be like:
IDManufacturer+ModelRange
1 Benz
1 E-Klasse
I tried all joins but I couldn't find the right one. Need some help! Thanks
I'm assuming you are trying to find the Models for a specific Manufacturer.
If you are filtering by the ID you don't need the JOIN as stated in the comments.
If you are filtering by the name you can do it with a INNER JOIN. Here is an example:
Declare
#myManufacturerChoice VARCHAR(100) = 'Mercedes';
SELECT
M.IDManufacturer,
mo.ModelRange Manufacturer
from Manufacturer M
inner join [Model range] mo on
M.IDManufacturer = mo.IDManufacturer
where
M.Manufacturer = #myManufacturerChoice
Also a reference link about joins.

Getting ROW_NUMBER to repeat if field meets a condition

I need ROW_NUMBER to assign data to a specific user if a condition is met.
ROW_NUMBER will increment normally until a duplicate value is found. When the duplicate value is found, I need it to use the same ROW_NUMBER until a new value is found.
For instance...
When using
SELECT ROW_NUMBER() OVER (ORDER BY COMPANY) AS rownum
,Company
,Contact
FROM TABLE
We can obviously expect this result
rownum Company Contact
1 BOB'S BURGERS BOB
2 STEVE'S SARDINES STEVE
3 STEVE'S SARDINES JERRY
4 STEVE'S SARDINES MARY
5 LARRY's LOBSTER LARRY
6 CHRIS' COWS CHRIS
What I'm trying to get is this. Whenever the Company name doesn't change, repeat the ROW_NUMBER and continue to increment the number when the company does change
rownum Company Contact
1 BOB'S BURGERS BOB
2 STEVE'S SARDINES STEVE
2 STEVE'S SARDINES JERRY
2 STEVE'S SARDINES MARY
3 LARRY'S LOBSTER LARRY
4 CHRIS' COWS CHRIS
I'm using this condition to see if the company matches the previous company name. It returns a 2 if the condition is true
ROW_NUMBER() OVER (PARTITION BY COMPANY ORDER BY COMPANY) AS SameCompany
You want DENSE_RANK not ROW_NUMBER. Try this:
SELECT DENSE_RANK() OVER (ORDER BY COMPANY) AS rownum
,Company
,Contact
FROM TABLE

Resources