Reputation: 419
I have a scenario as below:
Source1
Column1
Column2
Source2
Column1
Column2
Output - I need a view;
All the records in Source1 where Column2 is not empty must be in the view.
All the records in Source1 where Column2 is empty must be joined with Source2 (on Column1, the reference between both tables). Wherever it finds a match then Column2 of Source2 should also be included in the view.
Any pointers please..
Upvotes: 2
Views: 51
Reputation: 108400
Use an outer join between Source1
and Source2
.
The specification is a little loose. Did you want the Column2
from Source2
to be returned as a separate (third) column, or did you want the value from that in the second column, replacing the "empty" value of Column2
from Source1
?
What are the datatypes of Column2
in Source1
and Source2
? Is that character type, numeric, datetime?
How do you define "empty"? For character types, does that include both NULL values and zero length strings?
Also, what is the cardinality of the relationship between the tables, is it one to one, one to many (which way). Is it it mandatory, or possibly one to zero?
Assuming you want all the rows (if there are multiple rows from Source2
that match a row from Source1
, and assuming you want a third column, and assuming the datatype of Column2
is character, and assuming "empty" means NULL or zero-length string (that's a whole lot of assumptions)... then something like this:
SELECT s.column1
, s.column2
, IF(IFNULL(s.column2,'')='',t.column2,'') AS t_column2
FROM source1 s
LEFT
JOIN source2 t
ON t.column1 = s.column1
AND IFNULL(s.column2,'') = ''
ORDER BY s.column1, 2, 3
... will return a result that meets the specification. That query can be altered/tweaked to adjust to a tighter (more precise) specification.
EDIT
Ooops.
The example query above was based on yet another assumption: that this was specific to MySQL.
The syntax of the statement above won't "work" in other databases. Here's an equivalent statement, using more ANSI-standards compliant syntax:
SELECT s.column1
, s.column2
, CASE WHEN s.column2 IS NULL OR s.column2 = ''
THEN t.column2
ELSE ''
END AS t_column2
FROM source1 s
LEFT
JOIN source2 t
ON t.column1 = s.column1
AND (s.column2 IS NULL OR s.column2 = '')
ORDER BY s.column1, s.column2
FOLLOWUP
Added an example that demonstrates the behavior:
SQL Fiddle here: http://sqlfiddle.com/#!9/113e6/1
Setup tables and sample rows:
CREATE TABLE source1
( id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY
, column1 INT
, column2 VARCHAR(8)
);
CREATE TABLE source2
( id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY
, column1 INT
, column2 VARCHAR(8)
);
INSERT INTO source1 (id, column1, column2) VALUES
(1,NULL,NULL)
,(2,NULL,'foo')
,(3,113,'fee')
,(4,114,'fi')
,(5,115,'')
,(6,116,NULL)
,(7,122,'fo')
,(8,122,'fum')
;
INSERT INTO source2 (id, column1, column2) VALUES
(21,NULL,'doh')
,(22,113,'rey')
,(23,113,'mii')
,(24,114,'fah')
,(25,115,'sew')
,(26,115,'lah')
,(27,116,NULL)
,(28,116,'')
,(29,116,'tea')
,(30,116,'doh')
;
Example query (same as query above):
SELECT s.column1
, s.column2
, IF(IFNULL(s.column2,'')='',t.column2,'') AS t_column2
FROM source1 s
LEFT
JOIN source2 t
ON t.column1 = s.column1
AND IFNULL(s.column2,'') = ''
ORDER BY s.column1, 2, 3
Example query - same as query above PLUS extra id columns
SELECT s.column1
, s.column2
, IF(IFNULL(s.column2,'')='',t.column2,'') AS t_column2
-- ---------------
, s.id AS s_id
, t.id AS t_id
-- ---------------
FROM source1 s
LEFT
JOIN source2 t
ON t.column1 = s.column1
AND IFNULL(s.column2,'') = ''
ORDER BY s.column1, 2, 3
Returns:
column1 column2 t_column2 s_id t_id
------- ------- --------- ------ --------
(NULL) (NULL) (NULL) 1 (NULL)
(NULL) foo 2 (NULL)
113 fee 3 (NULL)
114 fi 4 (NULL)
115 lah 5 26
115 sew 5 25
116 (NULL) (NULL) 6 27
116 (NULL) 6 28
116 (NULL) doh 6 30
116 (NULL) tea 6 29
122 fo 7 (NULL)
122 fum 8 (NULL)
Note that this example includes "duplicate" values in column1, of both source1
and source2
, and shows the results that are returned. (The s_id
and t_id
columns are included to aid in deciphering the rows returned.)
Upvotes: 1
Reputation: 486
So to recap: only include lines where Source1.Column2 is populated, and include Column2 of Source2 as well if that is also populated?
What you're looking for is a LEFT JOIN
. Learn it and love it, because it's one of the handiest things in the whole of SQL.
SELECT s1.Column1, s1.Column2, s2.Column2
FROM source1 s1
LEFT JOIN source2 s2 ON s1.Column1 = s2.Column1
WHERE s1.Column2 IS NOT NULL
Upvotes: 1
Reputation: 2037
The easiest way I see is with an union of both queries:
SELECT * FROM Source1 WHERE Column2 IS NOT NULL
UNION
SELECT S2.* FROM Source1 S1
INNER JOIN Source2 S2
ON S1.Column1 = S2.Column1
WHERE S1.Column2 IS NULL
Upvotes: 1