Data query to keep the common data - sql

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.

Related

3 tables (1 bridge) select where table 3 does NOT have an entry in table 1

That was a hard question to phrase. Let me clarify
Table 1: ID1
Table 2: ID1, ID2
Table 3: ID2
the ID is NOT a key, and can be NULL. Each table represents a station, so in the world, they enter in an ID1 of 19 at table (station) 2, then and ID2 there as well. It is then entered in at table (station) 3.
For whatever reason they did not enter anything into table 1...maybe the line was going too fast.
Table 2 Should contain and entry to tie together each ID1 and and 2
ID1 = 19 -Table 1
ID2 = 29 -Table 3
Table 2 should then contain an entry:
ID1 19, ID2 29
However, this is not always the case. sometimes ids are 'lost' in transit, like in the above example.
I would like to find a way that I could see if I could see any entries in table 3 that do not have a corresponding entry in table 1. so the result would look like:
ID1 = NULL ID2 = 19 ID3 = 29
You can simply use a LEFT OUTER JOIN paired with a WHERE <value> IS NULL.
SELECT ID
FROM table_3 as three
INNER JOIN table_2 as two
ON two.ID2 = three.ID2
LEFT OUTER JOIN table_1 as one
ON one.ID = two.ID1
WHERE one.ID IS NULL
AND three.ID IS NOT NULL ;
Based on your comment:
I would like to find a way that I could see if I could see any entries in table 3 that do not have a corresponding entry in table 1
I feel as if you're eluding to being able to do the following:
SELECT * FROM table3 t3
LEFT JOIN table1 t1 ON t3.id=t1.id
WHERE t1.ID IS NULL
This is a pretty standard technique to find x missing from table y. Its also a common interview question.
You could also do this:
SELECT *
FROM table3 t3
WHERE NOT EXISTS
(
SELECT id
FROM table1
WHERE id = t3.id
)

SQL Subquery Join and Sum

I have Table 1 & 2 with common Column name ID in both.
Table 1 has duplicate entries of rows which I was able to trim using:
SELECT DISTINCT
Table 2 has duplicate numeric entries(dollarspent) for ID's which I needed and was able to sum up:
Table 1 Table 2
------------ ------------------
ID spec ID Dol1 Dol2
54 A 54 1 0
54 A 54 2 1
55 B 55 0 2
56 C 55 3 0
-I need to join these two queries into one so I get a resultant JOIN of Table 1 & Table 2 ON column ID, (a) without duplicates in Table 1 & (b) Summed $ values from Table 2
For eg:
NewTable
----------------------------------------
ID Spec Dol1 Dol2
54 A 3 1
55 B 3 2
Notes : No. of rows in Table 1 and 2 are not the same.
Thanks
Use a derived table to get the distinct values from table1 and simply join to table 2 and use aggregation.
The issue you have is you have a M:M relationship between table1 and table2. You need it to be a 1:M for the summations to be accurate. Thus we derive t1 from table1 by using a select distinct to give us the unique records in the 1:M relationship (assuming specs are same for each ID)
SELECT T1.ID, T1.Spec, Sum(T2.Dol1) as Dol1, sum(T2.Dol2) as Dol2
FROM (SELECT distinct ID, spec
FROM table1) T1
INNER JOIN table2 T2
on t2.ID = T1.ID
GROUP BY T1.ID, T1.Spec
This does assume you only want records that exist in both. Otherwise we may need to use an (LEFT, RIGHT, or FULL) outer join; depending on desired results.
I can't really see your data, but you might want to try:
SELECT DISTINCT ID
FROM TblOne
UNION ALL
SELECT DISTINCT ID, SUM(Dol)
FROM TblTwo
GROUP BY ID
Pre-aggregate table 2 and then join:
select t1.id, t1.spec, t2.dol1, t2.dol2
from (select t2.id, sum(dol1) as dol1, sum(dol2) as dol2
from table2 t2
group by t2.id
) t2 join
(select distinct t1.id, t1.spec
from table1 t1
) t1
on t1.id = t2.id;
For your data examples, you don't need to pre-aggregate table 2. This gives the correct sums -- albeit in multiple rows -- if table1 has multiple specs for a given id.

After Table Joining, need specific row value based on another Row with same ID

I have 2 tables as follows:
Table 1:
ID FName
1 Basics
2 Machine1
3 master
4 Machine2
15 Machine3
16 Machine16
Table 2:
ParentID Name InitialValue
1 Active 1
2 MachineName Entrylevel
2 Active 1
3 Active 1
4 MachineName Midlevellevel
4 Active 1
15 MachineName Endlevel
15 Active 1
16 MachineName Miscellenious
16 Active 0
Here, ID of Table 1 is referred as Parent ID at Table 2. I want "Initial Value" of Table 2 for MachineName Rows (of Table 2) provided "InitialValue" of Table 2 for Active Rows (of Table 2) are 1
Result should be like
ID InitialValue
2 Entrylevel
4 Midlevellevel
15 Endlevel
You could join the second table twice, once for MachineName, and once for Active:
SELECT t.ID, machine.InitialValue
FROM table1 t
INNER JOIN table2 machine
ON t.ID = machine.ParentId
AND machine.Name = 'MachineName'
INNER JOIN table2 active
ON t.ID = active.ParentId
AND active.Name = 'Active'
AND active.InitialValue = 1;
About Joins
The JOIN syntax allows you to link records to the previous table in your FROM list, most of the time via a relationship of foreign key - primary key. In a distant past, we used to do that with a WHERE condition, but that really is outdated syntax.
In the above query, that relationship of primary key - foreign key is expressed with t.ID = machine.ParentId in the first case. Note the alias that was defined for table2, so we can refer to it with machine.
Some extra condition(s) are added to the join condition, such as machine.Name = 'MachineName'. Those could just as well have been placed in a WHERE clause, but I like it this way.
Then the same table is joined again, this time with another alias. This time it filters the "Active" 1 records. Note that if the ID in table1 does not have a matching record with those conditions, that parent record will be excluded from the results.
So now we have the table1 records with a matching "MachineName" record and are sure there is an "Active" 1 record for it as well. This is what needs to be output.
Not sure if this is standard SQL but it should work using MySQL.
select T1.ID, T2.InitialValue
from Table1 T1 inner join Table2 T2 on T1.ID = T2.ParentId
where
T2.Name <> 'Active'
and exists (
select * from Table2 T3 where T3.ParentId = T1.ID and T3.Name = 'Active' and T3.InitialValue = 1
)
SELECT t1.ID, t2.InitialValue
FROM table1 t1 join table2 t2 on t1.ID=t2.ParentID
WHERE t2.name LIKE 'MachineName'AND t1.ID= ANY(SELECT t22.ParentID
FROM table2 t22
WHERE t22.InitialValue=1)
I think this should work
//slightly changed the condition in WHERE clausule (t2.parentID changed to t1.ID)

Lookup two columns using SQL

I have a task. For Instance, I have 2 tables.
Table 1 columns ID, Name
Table 2 columns ID, Name
Data is like in Table 1:
ID Name
1 A
2 B
3 C
Data is like in Table 2:
ID Name
1 D
2 B
3 E
I want to write a SQL query which lookup two tables in both columns. I want to have the count, which records not matching (both columns) with table 2.
Here only one record was matched (2 B). So, I should get the count 2.
Thanks.
Use not exists to count the # of rows in table1 that are not in table2
select count(*) from mytable t1
where not exists (
select 1 from mytable t2
where t2.id = t1.id
and t2.name = t1.name
)

Best way to filter hierarchical data using T-SQL?

Table1 has a list of items.
Table2 has a list of groups the items can be associated with.
Table3 is a cross-reference between 1 and 2.
The groups in table 2 are set up in hierarchical fashion.
Key ParentKey Name
1 NULL TopGroup1
2 NULL TopGroup2
3 1 MiddleGroup1
4 2 MiddleGroup2
5 3 NextGroup1
6 4 NextGroup1
7 2 MiddleGroup3
I want to be able to select from Table1 filtered by Table3.
Select Items from Table1 Where Table3.ParentKey NOT '2' or any of it's descendants.
From another post here on stackoverflow I've been able to use CTE to identify the hierarchy.
WITH Parent AS
(
SELECT
table2.Key,
cast(table2.Key as varchar(128)) AS Path
FROM
table2
WHERE
table2.ParentKey IS NULL
UNION ALL
SELECT
TH.Key,
CONVERT(varchar(128), Parent.Path + ',' + CONVERT(varchar(128),TH.Key)) AS Path
FROM
table2 TH
INNER JOIN
Parent
ON
Parent.Key = TH.ParentKey
)
SELECT * FROM Parent
I guess this is really a two part question.
How do you filter the above? For example, return all groups where TopGroup1 isn't in the lineage.
How would I apply that to filtering results in the cross-referenced table1.
There is a whole book on this topic, see: 'Joe Celko's Trees and Hierarchies in SQL for Smarties'
Personally, when I had to solve this problem, I used a temp table to unroll the hierarchy and then selected stuff from the temp table. Essentially you can build up another layer in the temp table in a single query, usually hierarchies are only 5-10 layers deep, so you can unroll it in 5 to 10 queries.
Try this
-- Table1 (ItemKey as PK, rest of the columns)
-- Table2 (as you defined with Key as PK)
-- Table3 (ItemKey as FK referencing Table1(ItemKey),
-- GroupKey as FK referencing Table2(Key))
Declare #Exclude int
Set #Exclude = 2
;WITH Groups AS -- returns keys of groups where key is not equal
( -- to #Exclude or any of his descendants
SELECT t.Key
FROM table2 t
WHERE t.ParentKey IS NULL
and t.Key <> #Exclude
UNION ALL
SELECT th.Key,
FROM table2 th
INNER JOIN Groups g ON g.Key = th.ParentKey
Where th.Key <> #Exclude
)
SELECT t1.*
FROM Table1 t1
WHERE t1.key in (Select t3.ItemKey
From table3 t3
Inner Join Groups g2
on t3.GroupKey = g2.Key
)