How to determine if there is a missing value in joined table - sql

I am trying to find the "users" that are missing a value in a 2nd table with the value of column "A" = 16 and then column "B" = 0.
I am looking for these values because that would give me the ability to run a query adding a row for each user that is missing the row with the values of A = 16 and B = 0.
So here is the relevant structure of the tables that we would be joining on.
There are two tables, table 1 and table 2
Table 1
ID
parent id
table 2
table1_id
A
B
The problem I am running into is that table2 can have records associated with the table1_id but still needing to verify if the table2 if there is not a row with table1_id, A missing value 16 while B is missing value 0.
Here is the current idea I am working off of for the sql query
SELECT
*
FROM
table1
LEFT JOIN
table2 ON table1.id = table2.table1_id
WHERE
table1.id IS NOT NULL
AND table2.id IS NULL;
This will give me all the table1_ids that are missing records from table2 but does however would not pull the rows where there are rows for the table1_id but however does not determine if there are missing rows with the column A with value 16 or Column B = 0.
If you are able to answer that would be greatly appreciated. I just currently cannot think of a way I can logically create a query that would do this.

So, you want all rows from table 1
And you want rows from table 2 that are A=16, B=0
And you want to know where the relationship breaks down between table1 and table2:
SELECT t1.*
FROM
table1 t1
LEFT JOIN
(
SELECT * FROM table2 WHERE A=16 and B=0
) a16b0
ON
t1.id = a16b0.table1_id
WHERE
a16b0.table1_id IS NULL
There are more ways to skin this cat, but this should be fairly understandable in the sense of "join table1 to (just the a16/b0 rows from table2)"
Another form you might get on with uses EXISTS:
SELECT * FROM table1 t1
WHERE NOT EXISTS(
SELECT null FROM table2 t2
WHERE t2.table1_id = t1.id AND t2.A = 16 AND t2.B = 0
)
In english it's "Select all from table 1 where, for any particular t1 row, there does not exist a t2 row that has: a matching id in table1_id, a 16 in a, a 0 in b"
A slightly less popular form (historical performance reasons probably) would be perhaps:
SELECT * FROM table1 t1
WHERE id NOT IN (
SELECT table1_id FROM table2 WHERE A = 16 AND B = 0
)
"select everything from table1 where the row's id is not in the list of IDs that are a16/b0 from table 2" - in essence this forms a "big list of everything we dont want" and then says "get me everything that isn't in the list of don't-wants"

This is the solution.
SELECT
*
FROM
table1
LEFT JOIN
table1.id = table2.table1_id AND table2.A = 16 AND table2.B = 0
WHERE
table2.id IS NULL;
#jon Armstrong, thanks for the help.

Related

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)

Select records from one table based on records from another table

this is a simplified version of a problem I'm having,
I have two tables:
Table1 has two columns (Stuff, YesNo) and
Table2 has one column (Stuff)
The records in the YesNo Column will either be 1 or 0
How could I select records in Table2 where the records in Table1.YesNo = 1
Many Thanks
SELECT Table2.*
FROM Table2
INNER JOIN Table1 ON Table1.Stuff = Table2.Stuff
WHERE Table1.YesNo = 1
If I understand you correctly, this would be your solution:
Select Stuff From Table2
Where Exists (
Select 'Y'
From Table1
Where Table1.Stuff = Table2.Stuff
And YesNo = 1
)
As I believe you'll need data from both tables and you may want to render fields unique to each table This seems like a likely response. However, as I don't believe STUFF accurately represents the relationship... you'll need to quantify/adjust the on a.stuff = b.stuff so that the join includes all necessary fields.
SELECT A.Stuff, B.Stuff, B.YesNo
FROM table1 B
INNER JOIN table2 A
on A.Stuff = B.Stuff
WHERE B.YesNo = 1
SELECT T2.*
FROM TABLE1 T1
JOIN TABLE2 T2
ON T1.Stuff = T2.Stuff
WHERE T1.YesNo = 1

how to make a simple query that matches column values to a look-up then matches further columns if no match is found

This is a simplified version of a problem I have. Say I’ve got three variables all of the same type, in three columns of table1, and an id field. They are all codes. Mostly they map to variables (group identifyers say) contained in a look up in table2. I want to write a query that does the following:
For each of my records I want to return the variable in table2 that my matches the code in the first of the three columns in table1. However, if the variable in this column contains a value that does not have a match in table2, I want to try for a match using column2. If that one does not match, use the one in column3.
I want the query result to contain the ID from table1 and the match from table2. If there is no match at all, then I want the query to contain a row with the id and n/a.
In this example there are just two values that match in my lookup. I'm actually mapping across 12 columns with a few hundreds of unique code values and several million rows of data.
Table1
id col1 col2 col3
1 V21 G22 T21
2 E30 W21 S34
3 Y11 U29 Q66
Table2
cat_code class_group
V21 group1
W21 group2
Query result
id class_group
1 group1
2 group2
3 n/a
So here in the desired result the record id 1 gets to match the very first column, and returns the corresponding variable, the second record can't get a match on the first but finds one on the second column and the third records can't match any value in any of the three columns so it throws an n/a.
I'm fairly new to SQL - I'm not sure whether this can be achieved in a simple query or whether it needs a functon.
select t1.id,
coalesce(t21.class_group, t22.class_group, t23.class_group) class_group
from Table1 t1
left join Table2 t21 on t21.cat_code = t1.col1
left join Table2 t22 on t22.cat_code = t1.col2
left join Table2 t23 on t23.cat_code = t1.col3
Just like Joel wrote... but he's quicker than I am :)
SELECT [Id], COALESCE(C1.[class_group], C2.[class_group], C2.[class_group], 'N/A')
FROM Table1 AS T1
LEFT JOIN Table2 AS C1 ON C1.[cat_code] = T1.[col1]
LEFT JOIN Table2 AS C2 ON C2.[cat_code] = T1.[col2]
LEFT JOIN Table2 AS C3 ON C3.[cat_code] = T1.[col3]
http://sqlfiddle.com/#!6/ffb01/3
Try this sql query:
SELECT table1.id, table2.class_group
FROM table1
INNER JOIN table2 ON table1.col1 = table2.cat_code
UNION
SELECT table1.id, table2.class_group
FROM table1
INNER JOIN table2 ON table1.col2 = table2.cat_code
SELECT table1.id, table2.class_group
FROM table1
INNER JOIN table2 ON table1.col3 = table2.cat_code

Update SQL statement only if two values match in another table

I have been searching for this scenario that has come across my desk, I have been searching reference sites but haven't had luck creating the correct SQL statement to complete this task.
Here is the PSEUDO code for the scenario.
UPDATE TABLE1
SET TABLE1.ID = TABLE1.From_ID,
TABLE1.VALUE = 'ALL'
WHERE TABLE1.From_ID = TABLE2.ID
AND TABLE2.NAME = 'TEST'
Basically I need to update two columns in TABLE1 only if the id from TABLE1 matches the ID's in the TABLE2 and the description column in TABLE2 equals to a string value the caveat is that TABL1 columns can't be change only if there is a correlation between the ID's from TABLE1 and TABLE2 and in TABLE2 that ID correlates to description column for a specific string value. Below is table structure and end result I'm trying to get too.
TABLE1:
FIELD_ID CONDITIONAL_VALUE FROM_FIELDID
--------------------------------------------
1 TEST 3
7 TEST 4
5 ANY 7
TABLE2:
FIELD_ID Description
----------------------------------------------
3 BLUE
4 BLUE
7 RED
In Transact-SQL (SQL Server's dialect of SQL), you need a FROM clause in your SQL if you specify more than the table you're trying to update.
update
TABLE1.ID
set
TABLE1.ID = TABLE1.From_ID ,
TABLE1.VALUE = 'ALL'
from
TABLE1,
TABLE2
where
TABLE1.From_ID = TABLE2.ID
AND TABLE2.NAME = ''TEST
You need to join data from TABLE1 to TABLE2
UPDATE t1
SET t1.ID = t1.From_ID
,t1.VALUE = 'ALL'
FROM Table1 AS t1
JOIN table2 AS t2
ON t1.From_ID = t2.ID
AND t2.NAME = 'TEST't1

How do I Write a SQL Query With a Condition Involving a Second Table?

Table1
...
LogEntryID *PrimaryKey*
Value
ThresholdID - - - Link to the appropriate threshold being applied to this log entry.
...
Table2
...
ThresholdID *PrimaryKey*
Threshold
...
All fields are integers.
The "..." thingies are there to show that these tables hold a lot more imformation than just this. They are set up this way for a reason, and I can't change it at this point.
I need write a SQL statement to select every record from Table1 where the Value field in that particular log record is less than the Threshold field in the linked record of Table2.
I'm newish to SQL, so I know this is a basic question.
If anyone can show me how this SQL statement would be structured, it would be greatly appreciated.
SELECT T1.*
FROM Table1 T1
JOIN Table2 T2 ON T2.ThresholdID = T1.ThresholdID
WHERE T2.Threshold > T1.Value
SELECT t1.*
FROM dbo.Table1 t1 INNER JOIN dbo.Table2 t2 ON t1.ThresholdID = t2.ThresholdID
WHERE t2.Threshold > t1.Value
SELECT * from table1 t1 join table2 t2 on (t1.thresholdId = t2.thresholdId)
where t1.value < t2.threshold;
SELECT t1.LogEntryID, t1.Value, t1.ThresholdID
FROM Table1 t1
INNER JOIN Table2 t2 ON t1.ThresholdID = t2.ThresholdID
WHERE t1.Value < t2.threshold
SELECT * FROM Table1
JOIN Table2
ON table1.ThresholdID = table2.ThresholdID --(assuming table 2 holds the same value to link them together)
WHERE
value < thresholdvalue
A 'JOIN' connects 2 tables based on the 'ON' clause (which can be multipart, using 'AND' and 'OR')
If you have 3 entries in table 2 which share table1's primary key (a one-to-many association) you will receive 3 rows in your result set.
for the tables below, for example:
Table 1:
Key Value
1 Hi
2 Bye
Table 2:
Table1Key 2nd_word
1 You
1 fellow
1 friend
2 now
this query:
SELECT * FROM Table1
JOIN Table2
on table1.key = table2.table1key
gets this result set:
Key Value Table1Key 2nd_word
1 Hi 1 You
1 Hi 1 fellow
1 Hi 1 friend
2 Bye 2 now
Note that JOIN will only return results when there is a match in the 2nd table, it will not return a result if there is no match. You can LEFT JOIN for that (all fields from the second table will be NULL).
JOINs can also be strung together, the result from the previous JOIN is used in place of the original table.