Question: I have the following query

```
select cand_id 
from cand_kw
WHERE client_id='mamasandpapas' AND UPPER(kw) LIKE '%MARAH%' OR UPPER(kw) LIKE '%ANDREW%' AND UPPER(kw) NOT LIKE '%KOCH%' 

```

In the database there are records with the following:

```
Andrew Postings
Andrew Postings
Andrew McDee
Marah Koch

```

So there are three rows with and Andrew in it but only one record with a Marah in it.

if I change my query to the following then the two Andrew Postings are excluded correclty

```
select cand_id
from cand_kw
 WHERE client_id='mamasandpapas' AND UPPER(kw) LIKE '%MARAH%' OR UPPER(kw) LIKE '%ANDREW%' AND UPPER(kw) NOT LIKE '%POSTINGS%' 

```

So it looks like if only one record exists then the results are returned even though they should be excluded.

This is using a very old version of Oracle (9i) and the field its search (kw) stands for keywords and is a CLOB containing a bunch of keywords.

This is a very old system not of my design.

Can anybody explain in the first case why Marah Koch is not being excluded and the Andrew Postings records are?

Answer: 
Simple vs recursive expansion makes no difference here; regardless of which you use you'll see the same behavior. A GNU make variable is *global* and obviously can have only one value.

You have to understand when variables are expanded. The documentation provides a [detailed description](https://www.gnu.org/software/make/manual/html_node/Reading-Makefiles.html) of this. Targets and prerequisites are expanded *when the makefile is read in*, so the value of `Targ` as the makefile is being parsed is used.

Recipes are expanded *when the recipe is to be invoked*, which is not until after all makefiles are parsed and make starts to build targets. At that time of course the variable `Targ` has its last set value.

Without knowing what your makefile really does it's hard to suggest an alternative. One option is to use target-specific variables:

```
Targ := A
$(Targ): LocalTarg := $(Targ)
$(Targ):
        @echo expect A, get $(LocalTarg), Target is $@

```

Another option is to use constructed variable names:

```
Targ := A
Targ_$(Targ) := $(Targ)
$(Targ):
        @echo expect A, get $(Targ_$@), Target is $@

```
Apologies for answering my own question, but I now realised it is possible to solve the issue I was having by running make recursively.

E.g. if the parameter variables for the rules are Targ, Param1 and Param2 then

```
#Set up "default" values for the parameters (As @madscientist points out, 
#these will safely be overridden by the defs on the @(make) commands below

Targ=XXXXXXXXXX
Param=XXXXXXXXXX
Param2=XXXXXXXXXX
Recursing=

#
# define N (==3) templated rule(s)
#
$(Targ)%a:
    @echo Run Combo_a $(Targ) $(Param1) $(Param2) $@

$(Targ)%b:
    @echo Run Combo_b $(Targ) $(Param2) $(Param1) reversed $@

$(Targ)%c:
    @echo Run Combo_c  $(Param1) $(Targ) $(Param2) mixed again $@

#
#Enumerate "M" (==2) sets of parameters, 
# (Except if we are already recursing because unrecognised targets may cause
# it to descend forever)
#
ifneq ($(Recursing), Yes)
Set1%:
    @$(MAKE) Targ=Set1 Param1=foo Param2=bar Recursing=Yes $@

Set2%:
    @$(MAKE) Targ=Set2 Param1=ray Param2=tracing Recursing=Yes $@
endif

```

This then allows N\*M different combos for N+M typing cost.
eg. (removing messages from make re recursion)

```
>make Set1.a
Run Combo_a Set1 foo bar Set1.a

>make Set2.c
Run Combo_c ray Set2 tracing mixed again Set2.c

```