You'll need to provide a different value parameter for each selectlist, otherwise they will all write into the same variable and the last to do it will become the value for all of them.
This is a great use case for a wrapper class, as that way you colocate the selected value with the rest of the information being presented in the datatable. For example, if you have a list of account sobjects, you'd have a wrapper class that holds the account and the selected value:
public class AccWrap
{
public Account acc {get; set;}
public String selVal {get; set;}
public AccWrap(Account acc)
{
this.acc=acc;
}
}
Then you'd build a list of these for display:
public List<AccWrap> wrappers {get; set;}
public MyController()
{
wrappers=new List<AccWrap>();
List<Account> accs=[select id, Name from Account limit 10];
for (Account acc : accs)
{
AccWrap wrap=new AccWrap(acc);
wrappers.add(wrap);
}
}
Then in the page, you'd use this collection to back the pageblocktable:
<apex:pageBlockTable value="{!wrappers}" var="wrap">
<apex:column value="{!wrap.Name}"/>
<apex:column headerValue="Choose">
<apex:selectList value="{!wrap.selVal}"/>
<apex:selectOptions value="{!myOptions}"/>
</apex:selectList>
</apex:column>
With regard to the onchange, you'd need to add an actionsupport to the selectlist to execute an action method when the onchange event happens. This would traverse the list of wrappers and populate any additional fields based on the value of 'selVal'.