On Mon, Oct 26, 2009 at 05:32:27PM -0700, Peter Haworth scratched on the wall: > Looking for a way to implement the following situation > > I need to select entries form TableA and TableB. The join needs to > happen using two separate fields. One of this fields can be used in > the normal way but the other filed needs some special logic > > The normal join field is ProdID and the unusual one is PriceTable. If > there are no entries in Table B for the values of ProdID and > ProceTable in the TableA entry then the join must happen using the > value TableA.ProdID and a constant value "STANDARD" to join the > PriceTable entries in TableB to TableA > > Here's an example > > TableA.ProdID TableA.PriceTable TableB.ProdID Tableb.PriceTable > 1 SPECIAL 1 SPECIAL > 1 SPECIAL 1 SPECIAL > 1 STANDARD 1 STANDARD > 2 SPECIAL 2 STANDARD > 2 SPECIAL 2 STANDARD >
You appear to have duplicate rows in your example, but here are two different ideas. We'll start with this: sqlite> CREATE TABLE TableA ( ProdID, PriceTable ); sqlite> CREATE TABLE TableB ( ProdID, PriceTable ); sqlite> sqlite> INSERT INTO TableA VALUES ( 1, 'STANDARD' ); sqlite> INSERT INTO TableA VALUES ( 1, 'SPECIAL' ); sqlite> INSERT INTO TableA VALUES ( 2, 'SPECIAL' ); sqlite> sqlite> INSERT INTO TableB VALUES ( 1, 'STANDARD' ); sqlite> INSERT INTO TableB VALUES ( 1, 'SPECIAL' ); sqlite> INSERT INTO TableB VALUES ( 2, 'STANDARD' ); First idea: sqlite> SELECT ...> A1.ProdID, ...> A1.PriceTable, ...> coalesce( B1.ProdID, B2.ProdID ), ...> coalesce( B1.PriceTable, B2.PriceTable ) ...> FROM TableA AS A1 ...> LEFT JOIN TableB AS B1 ...> ON ( A1.ProdID = B1.ProdID AND A1.PriceTable = B1.PriceTable ) ...> JOIN TableB AS B2 ...> ON ( A1.ProdID = B2.ProdID and 'STANDARD' = B2.PriceTable ); 1|STANDARD|1|STANDARD 1|SPECIAL|1|SPECIAL 2|SPECIAL|2|STANDARD As I understand it, you're basically trying to match both a ProdID and a PriceTable, but if a PriceTable cannot be found, you want to use the 'STANDARD' PriceTable. This basically JOINs TableA to TableB twice, one with an exact match and one with a 'STANDARD' match. The first match (A1/B1) is done as a LEFT OUTER JOIN, so any mis-matched rows are matched to NULL on the B1 side. The second match (A1/B2) is done as a standard INNER JOIN and assumes there will always be a 'STANDARD' row in TableB for every possible ProdID in TableA. We then use the coalesce() function to return either the valid exact-matched values from B1. If those are NULL, we return the 'STANDARD' match rows from B2. Here is another apprach that uses a CASE statement: sqlite> SELECT A1.*, B2.* ...> FROM TableA AS A1 ...> LEFT JOIN TableB AS B1 ...> ON ( A1.ProdID = B1.ProdID AND A1.PriceTable = B1.PriceTable) ...> JOIN TableB AS B2 ...> ON ( A1.ProdID = B2.ProdID AND B2.PriceTable = ( ...> CASE B1.PriceTable ...> WHEN B1.PriceTable THEN ...> A1.PriceTable ...> ELSE ...> 'STANDARD' ...> END ) ); 1|STANDARD|1|STANDARD 1|SPECIAL|1|SPECIAL 2|SPECIAL|2|STANDARD This is the same basic idea, in that we join TableA to TableB twice. The difference is that we only want the results of the second join (T1/B2) where we join against A1.PriceTable if we know we got a valid match the first time, or 'STANDARD' if we did not. The key to making that work is that ( B1.PriceTable = B1.PriceTable ) will be FALSE (and return the ELSE value) if B1.PriceTable is NULL. I'm sure there are a few other ways you could factor this problem using a double-join, but that's one baisc approach. The heart of the issue is that there is no way to test if a row has a match or not within a single JOIN. You must do the LEFT JOIN to see if there was a match or not. Then, based off the information of that JOIN, you can do the JOIN again and decide to take the values from the first match (if they're valid) or re-try with other values if they are not. -j -- Jay A. Kreibich < J A Y @ K R E I B I.C H > "Our opponent is an alien starship packed with atomic bombs. We have a protractor." "I'll go home and see if I can scrounge up a ruler and a piece of string." --from Anathem by Neal Stephenson _______________________________________________ sqlite-users mailing list sqlite-users@sqlite.org http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users