2015-02-04 13 views
6

Non so come esprimerlo in SQL, se è possibile, o come chiamarlo.Primo match non ancora utilizzato

Desidero, per ogni record della Tabella A, il primo record di corrispondenza migliore nella Tabella B che non sia stato già selezionato come migliore corrispondenza. Ad esempio, supponiamo di avere un generico Shopping List e un menù:

Table A      Table B 
Generic Shopping List  Food Menu 
---------------------  ---------------------- 
Food Type     Food  Food Type 
---------------------  ---------------------- 
Meat       Tomatoes Vegetable 
Meat       Lettuce  Vegetable 
Vegetable     Bacon  Vegetable 
Vegetable     Bacon  Meat 
Vegetable     Beef  Meat 
Vegetable     Apple  Fruit 
Fruit      Orange  Fruit 
Fruit      Bacon  Fruit 
Dairy      Milk  Dairy 
          Cheese  Dairy 
          Yogurt  Dairy 

Con una query o partecipare, è facile ottenere il Top 1 partita:

Table/Query C 
Automagic Shopping 
------------------ 
Food 
------------------ 
Bacon 
Bacon 
Tomatoes 
Tomatoes 
Tomatoes 
Tomatoes 
Apple 
Apple 
Milk 

So come fare e siccome mi piace il bacon, potrei vivere con questo. Sfortunatamente, ho davvero bisogno dell'intera gamma di opzioni alimentari disponibili, in modo tale che io abbia degli slot disponibili per questo.

Table/Query C 
Better Magic Shopping 
--------------------- 
Food 
--------------------- 
Bacon 
Beef 
Tomatoes 
Lettuce 
Bacon 
<NULL - No More Available Matches - Don't Care> 
Apple 
Orange 
Milk 

Se questo può essere fatto in Access, ottimo. Se non può essere fatto in Access, ma può essere fatto in un altro prodotto, non è l'ideale, ma è praticabile.

Grazie.

risposta

3

questo è un modo per farlo in SQL Server:

SELECT t1.FoodType, t2.Food 
FROM (
    SELECT *, ROW_NUMBER() OVER (PARTITION BY FoodType ORDER BY FoodType) AS rn 
    FROM #tableA) AS t1 
LEFT JOIN (
    SELECT *, ROW_NUMBER() OVER (PARTITION BY FoodType ORDER BY FoodType) AS rn 
    FROM #tableB) AS t2 ON t1.FoodType = t2.FoodType AND t1.rn = t2.rn 

Qui di seguito sono, fianco a fianco, le espressioni di tabella calcolati dai due subquery, t1, t2:

Results for t1:  Results for t2: 
FoodType rn  Food  FoodType rn 
---------------  -------------------------- 
Dairy  1   Milk  Dairy  1 
Fruit  1   Cheese Dairy  2 
Fruit  2   Yogurt Dairy  3 
Meat  1   Apple  Fruit  1 
Meat  2   Orange Fruit  2 
Vegetable 1   Bacon  Fruit  3 
Vegetable 2   Bacon  Meat  1 
Vegetable 3   Beef  Meat  2 
Vegetable 4   Tomatoes Vegetable 1 
         Lettuce Vegetable 2 
         Bacon  Vegetable 3 

Doing a LEFT JOIN su FoodType e rn ottieni quello che vuoi.

+0

Impressionante, e grazie! Per la mia edificazione, come si chiama questo tipo di problema? – Dave

+0

@Dave Ho paura di non poterti aiutare in questa domanda. 'ROW_NUMBER' è generalmente una funzione che si rivela utile in casi come questi, dove è richiesto un tipo di join ad hoc tra due set. –

0

L'accesso consente una clausola NOT IN. Basta scrivere la query per ottenere la partita TOP 1. Quindi includi questa query come sottoquery all'interno della clausola NOT IN.

Select * From Table_A A, Table_B B Where A.Food_Type = B.Food_Type And B.Food Not In (Select Top 1 D.Food From Table_A D, Table_B C Where D.Food_Type = D.Food_Type And C.Food_Type = 'give your criterion value here') 

Nota si potrebbe desiderare di un ordine adatto da clausola per descrivere come a determinare ciò che è un risultato migliore e ciò che non lo è.