0

I would like to create a query that populates a field in one table based on a keyword lookup (CONTAINS) referencing a keyword field from a different table. See sample tables below:

tbl_Parts
+----+------+-------------+------+
| ID | Comp |    Desc     | Type |
+----+------+-------------+------+
|  1 |  112 | Brg, Ball   |      |
|  2 |  245 | Bearing, X  |      |
|  3 |  364 | Mtg Ring, 1 |      |
|  4 |  445 | Pump, 2x3   |      |
+----+------+-------------+------+

tbl_Ref
+----+---------+-------+
| ID | Keyword | Type  |
+----+---------+-------+
|  1 | Bearing | O     |
|  2 | Ring    | S     |
|  3 | Pump    | P     |
|  4 | Disc    | O     |
+----+---------+-------+

Specifically, I would like to populate tbl_Parts.Type using tbl_Ref.Type WHERE tbl_Parts.Desc CONTAINS tbl_Ref.Keyword.

However, I have not been able to find any examples of the CONTAIN function that utilizes a field as reference. I would imagine the query would look similar to this:

SELECT *
FROM (
SELECT tbl_Parts.Comp, tbl_Parts.Desc, tbl_Ref.Type AS tbl_Parts.Type 
FROM tbl_Ref, tbl_Parts 
WHERE tbl_Parts.Desc CONTAINS tbl_Ref.Keyword
) AS x;

I know this is far from correct, but it's all I can conjure up at the moment.

There will also be instances where tbl_Parts.Desc contains multiple keywords. In this case, I would like to concatenate all type matches. However, this functionality is not priority at the moment.

It should be noted that I am okay with doing this in a lookup query within the Design of tbl_Parts, a standalone Query, or an Append Query.

Any advice or suggestions for this would be great, thanks in advance!

Erik A
  • 31,639
  • 12
  • 42
  • 67
Adam B
  • 37
  • 5

2 Answers2

0

CONTAINS requires string literal as second argument so I doubt it is possible that way.

CONTAINS (
{
column_name | ( column_list )
| *
| PROPERTY ( { column_name }, 'property_name' )
}
,'<contains_search_condition>' [ , LANGUAGE language_term ]
)

You could use LIKE instead:

SELECT tbl_Parts.Comp, tbl_Parts.Desc, tbl_Ref.Type AS [tbl_Parts_Type] 
FROM tbl_Ref
JOIN tbl_Parts 
  ON tbl_Parts.Desc LIKE '%' +  tbl_Ref.Keyword + '%';

There will also be instances where tbl_Parts.Desc contains multiple keywords. In this case, I would like to concatenate all type matches. However, this functionality is not priority at the moment.

SELECT tbl_parts.ID, tbl_Parts.Comp, tbl_Parts.Desc,
  STRING_AGG(tbl_Ref.Type, ',') WITHIN GROUP(ORDER BY tbl_Ref.ID) AS tbl_Parts_Type 
FROM tbl_Ref
JOIN tbl_Parts 
  ON tbl_Parts.Desc LIKE '%' +  tbl_Ref.Keyword + '%'
GROUP BY tbl_parts.ID, tbl_Parts.Comp, tbl_Parts.Desc;
Lukasz Szozda
  • 162,964
  • 23
  • 234
  • 275
  • I am struggling to get either method to work. Do these apply to Access as well? – Adam B Dec 28 '18 at 20:30
  • @AdamB First part should be working on both SQL Server. For MS Access you need to change `ON tbl_Parts.Desc LIKE '%' + tbl_Ref.Keyword + '%'` to `ON tbl_Parts.Desc LIKE "%" & tbl_Ref.Keyword & "%"` – Lukasz Szozda Dec 28 '18 at 21:46
  • I am still getting a syntax error with the STRING_AGG and FROM clause. It seems Access doesn't like the WITHIN or JOIN commands. Any suggestions? – Adam B Jan 02 '19 at 15:55
  • @AdamB Access does not support STRING_AGG/GROUP_CONCAT. You need to write own function: https://stackoverflow.com/questions/5517233/ms-access-query-concatenating-rows-through-a-query – Lukasz Szozda Jan 02 '19 at 15:57
0

Since you ultimately intend to populate the tbl_parts.type field (presumably using an UPDATE query) with the value obtained from your SELECT query, you'll likely need to use a domain aggregate function such as DLookup to obtain the appropriate value, else MS Access will complain that the query will not be updateable.

To this end, I would suggest the following:

update tbl_parts p
set p.type = dlookup("type", "tbl_ref", "'" & p.desc & "' like '*' & keyword & '*'")

This will of course be scuppered if tbl_parts.desc contains quote symbols.

Example:

enter image description here

enter image description here

After running above SQL:

enter image description here

In the circumstance that the description matches multiple keywords and you need to concatenate multiple types into a comma-delimited string then I would suggest constructing a SELECT query with selection criteria based on the criteria demonstrated in the DLookup expression above, and then iterate over a recordset of the results using VBA.

Lee Mac
  • 15,615
  • 6
  • 32
  • 80
  • Can you expand on this? I can get it to run with no syntax errors, but no results come from it. I am essentially running code as is (changed naming as necessary): `UPDATE [Data - Inventory] AS p SET p.type = dlookup("Type", "[Component Library]", "'" & p.Description & "' like '*' & Keyword & '*'");` – Adam B Jan 02 '19 at 15:53
  • @AdamB I've updated my answer with a screenshot of my test setup. Are you sure you have renamed the fields correctly? Do you receive the same results if you configure your tables as I have? – Lee Mac Jan 02 '19 at 18:18
  • thanks for the update. This was successful aside from a few type conversion failures. I assume the Dlookup would select the type of the first keyword match? Would there be a simple way of concatenating all type matches by chance? – Adam B Jan 03 '19 at 14:25
  • @AdamB I would assume that type conversion is due to the `dlookup` expression returning `null` for descriptions where no match is found, as the query is otherwise only working with string-valued fields and so no type conversion should be required. I have updated my answer with a description of how I would approach multiple keyword matches. – Lee Mac Jan 03 '19 at 18:26
  • I have more non matches than type conversions, so I don't believe nulls are the issue. I will attempt to pursue the multiple matches as suggested by you and Lukasz. I have chosen your method as the solution because it populates the original table simply, which was the main goal. However, for anyone reading this at a later time, Lukasz's approach is great too, provided you adjust the coding to the version of SQL you are using. – Adam B Jan 03 '19 at 18:49