Unique Select Query into Table Sqlite3 - sql

I have the following database structure
Table 1
EventID | Person1 | Person2 | Person3 | ... | PersonN
Table 2
Person | Height | Weight
Now I would like a query that for a given EventID (which is unique) returns the persons involved along with their Height and Weight.
I was thinking of creating some sort of temporary table along the lines of
CREATE TEMP TABLE t AS
SELECT Person1, Person2, Person3, ..., PersonN FROM Table1 WHERE EVENTID = ?
and then joining the temporary table t with table2 but of course this doesn't work as what I want is the transpose of t.
How would I go about doing this?

If you are given the event id, you can use exists:
select t2.*
from table2 t2
where exists (select 1
from table1 t1
where t2.person in (t1.person1, t1.person2, t1.person3) and
t1.eventid = $eventid
);
Your data structure, however, is not very suitable for scaling purposes. The problem data structure would have an EventPersons table, with one column for EventId and one column per PersonId.

select t2.person, t2.height, t2.weight
from table2 t2
join
(select person1 as person,event_id as person from table1
union select person2,event_id from table1..
select personN,event_id from table1) t3
on t3.person = t2.person
where t3.event_id = ?
This is the more generic approach i can think of. But as the comments mentions you should consider changing the table structure.

Related

SQL insert into table with values selected from other tables where an external value matches

I have the following tables:
Table1:
id
rarity
1
Common
2
Uncommon
3
Rare
Table2:
id
Type
1
Air
2
Earth
3
Fire
4
Water
The output table already exists and the schema is the following:
rarityID
weakness_typeID
resistance_typeID
and I should fill it with rows according to the Table2 and Table1.
For example if I'm given:
type is 'Water' and 'Air'
rarity is 'Common'
I'd like to add the IDs contained in Table1 and Table2 to this table to get the following updated output table:
rarityID
weakness_typeID
resistance_typeID
1
4
1
I've written the following query:
INSERT INTO table3 (rarityID, weakness_typeID, resistance_typeID)
SELECT rar.id, weak.id, res.id
FROM table1 rar, table2 weak, table2 res
WHERE rar.rarity = `Common`
AND weak.type = `Water`
AND res.type = `Air`;
But it doesn't work, can you help me?
My understanding of your problem is that you're trying to get ids for each of your information.
If this is correct, in order to do this you need to select their ids in three separate queries like it is done in the following query:
INSERT INTO table3 (rarityID, weakness_typeID, resistance_typeID)
SELECT (SELECT rar.id
FROM table1 rar
WHERE rar.rarity = 'Common') AS rarityID,
(SELECT weak.id
FROM table2 weak
WHERE weak.type = 'Water') AS weakness_typeID,
(SELECT weak.id
FROM table2 weak
WHERE weak.type = 'Air') AS resistance_typeID;
If you want to play with this code, check this SQL Fiddle.

Data query to keep the common data

I have a table
Table 1 : It the final table contains all data .
ID and IDS are composite key
ID IDS name
1 PL35 Bumper
151111 PL35 Bumper
151111 PL36 Bumper
1516 PL35 TUMI
151511 PL36 Limo
151521 PL35 Superb
151521 PL36 Superb
table 2 : Its a pre final table which will upcoming data with incomplete information
ID IDS name
15100 PL35 NULL
1516 PL35 NULL
151521 PL36 NULL
151511 PL36 NULL
EXPECTED RESULT : Some IDs (ID+IDS) are in Table 1 and some are in Table 2 . I need to compare the data of table 1 and table 2 .
The rule is
Keep the common data with Table 1 information
Keep the new row with (id+IDS) which is in table 2 but not in table 1
for eg;
(15100 + PL35) is in table 2 but not in table 1 then it will remain
(1516 + PL35) is common in both then the row from table 1 will
remain.
( 151511 + PL36) is also common hence will remain .
The data (ID +IDs) which is not in table 2 but in table 1 is not needed.
ID IDS name
15100 PL35 NULL
1516 PL35 TUMI
151511 PL36 Superb
SO far I am only think about this
select * from table1 t1
inner join table2 t2 on t1.id=t2.id
Use INTERSECT, named after the equivalent set operation.
SELECT
ID,
IDS
FROM
table1
INTERSECT
SELECT
ID,
IDS
FROM
table2
EDIT
In answer to your question, you can wrap this in a CTE and then join back onto table1.
WITH common AS
(
SELECT
ID,
IDS
FROM
table1
INTERSECT
SELECT
ID,
IDS
FROM
table2
)
SELECT
c.*,
t.Name
FROM common c
INNER JOIN
table1 t
ON c.ID = t.ID
AND c.IDS = t.IDS
I think you can use FULL OUTER JOIN, and put a WHERE condition WHERE t1.id NOT NULL and t2.id NOT NULL.

sql merge two select query results, keep result from query A if there is a conflict on one column's value

result set 1:
id | animal
1 | panda
2 | duck
result set 2:
id | animal
1 | horse
3 | dog
desired result after merge
id | animal
1 | panda
2 | duck
3 | dog
is there a better way than check if the id exists in first when select the 2nd?
You can do this with not exists:
select t1.id, t1.animal
from table1 t1
union all
select t2.id, t2.animal
from table2 t2
where not exists (select 1 from table1 t1 where t1.id = t2.id);
It would be interesting to compare the performance of this with the performance of the full join version. The explain plans of the two methods are surprisingly interesting.
Without any primary keys on the tables, this version is much, much faster than the full join version. With primary keys, the full join is a bit faster. In both cases, the union all should be faster for returning the first row.
What I don't understand is that the plan for the not exists version without primary keys is faster than the version with primary keys. The mysteries of database optimizers.
This looks like a full join and coalesce() for priorization:
select id, coalesce(t1.animal, t2.animal) animal
from table1 t1 full join
table2 t2
using (id)
Just union all the two first then group by having count() >1
Select * from( Select distinct id,
animal from table
Union all
Select distinct id, animal from table)
Group by id, animal having count(*)
>1;

Remove Duplicate Data Based on Three Fields and Two tables

I have two tables that have more than three fields each. There is a group of records that are on both files, the below is a mock example:
Table 1:
ID Name Town State
1 Dave Chicago IL
2 Mark Tea MD
Table 2:
ID Name State Job Married
1 Dave IL Manager Yes
2 Mark MD Driver No
For my purpose duplicates exist if ID, Name, and State are the same. So the above data are duplicates. How do I delete them from one table (I have over 900 duplicates so deleting one by one is not possible)?
delete table1
where ID in(select distinct ID from table1 where ID in (Select ID from table2))
i dont understand which table has duplicates, if you want to delete duplicate data from one table1 then you can use this query
This query will produce a de-duplicated result set:
SELECT Table1.ID,
Table1.NAME,
Table1.Town,
Table1.STATE,
NULL AS Job,
NULL AS Married
FROM Table1
WHERE Table1.ID NOT IN (
SELECT Table1.ID
FROM Table1
INNER JOIN Table2 ON (Table2.STATE = Table1.STATE)
AND (Table2.NAME = Table1.NAME)
AND (Table1.ID = Table2.ID)
)
UNION
SELECT Table2.ID,
Table2.NAME,
NULL AS Town,
Table2.STATE,
Table2.Job,
Table2.Married
FROM Table2
This is the most straightforward way to do it, assuming that you want to delete from Table1. I'm a little rusty with Access SQL syntax, but I believe this works:
DELETE FROM [Table1]
WHERE EXISTS (
SELECT 1
FROM [Table2]
WHERE [Table2].[ID] = [Table1].[ID]
AND [Table2].[Name] = [Table1].[Name]
AND [Table2].[State] = [Table1].[State]
)

How to query two tables to compare data

I'm having trouble coming up with a way to compare some data in SQL Server (2005). I have two tables and I need to make sure that the values from table 1 are matched in table two. Here's the table structure and some example data.
Table 1
GenreId
6
This is a temp table with a list of IDs that are passed in.
Table 2
Show| GenreId
Show1 | 2
Show1 | 6
Show2 | 6
This table can have many GenreIds for a show. The results that I am trying to figure out how to retrieve are that I only need shows that only have the GenreIds from table 1. So the results I expect in the end would be:
If table 1 has 6, I expect to ONLY get Show2. If table 1 has 2 and 6, then I get Show1 and Show2.
I know this is probably simple but I am really drawing a blank. Any help is very much appreciated.
This is the query you're looking for:
SELECT SHOW FROM t2
WHERE SHOW NOT IN (
SELECT SHOW FROM t2
WHERE genreId NOT IN (6, 2)
)
GROUP BY SHOW
HAVING count(DISTINCT genreId) = 2
Those queries are a bit tricky. Take into account that the number in the HAVING clause have to match the AMOUNT of items in the IN clause.
Now, provided that you have a table that contains those IDs, then you can solve it this way:
SELECT SHOW FROM t2
WHERE SHOW NOT IN (
SELECT SHOW FROM t2
WHERE genreId NOT IN (
SELECT genreId FROM t1
)
)
GROUP BY SHOW
HAVING count(DISTINCT genreId) = (SELECT COUNT(*) FROM t1)
Fiddle here.
If table 1 has 6, I expect to ONLY get Show2. If table 1 has 2 and 6,
then I get Show1 and Show2.
Fiddle demo (Demo is on Sql Server 2012 but query should work on 2005):
select Max([show]) myShow
from T2 join T1
on T2.GenreId = T1.GenreId
Group by T2.GenreId;
Well, this should work but it may have horrible performance if Table2 is large...
SELECT * FROM Table2 t2
WHERE NOT EXISTS(
SELECT GenreID
FROM Table1
WHERE GenreID NOT IN (
SELECT GenreID
FROM Table2
WHERE Show = t2.Show))
AND NOT EXISTS(
SELECT GenreID
FROM Table2
WHERE GenreID NOT IN (
SELECT GenreID FROM Table1)
AND Show = t2.Show)
select Show from Table2
inner join Table1
on Table1.GenreId = Table2.GenreId
Use this query. It checks if the show is the only show for the selected genre.
SELECT DISTINCT Show FROM Table2
INNER JOIN Table1 ON Table1.GenreId = Table2.GenreId
AND (SELECT Count(DISTINCT GenreId) FROM Table2 T2 WHERE Table2.Show = T2.Show) = 1
My bad. I understand what you're asking now, I think.
This?
select Show from Table2
where genreid in (select genreid from Table1)
except
select Show from Table2
where genreid not in (select Genreid from Table1)