**SET(***recordset, expression*
**[, UNORDERED | ORDERED(** *bool
***) ] [, STABLE | UNSTABLE ] [, PARALLEL [
(** *numthreads ***) ] ] [,
ALGORITHM(** *name ***) ]
)**

recordset | The set of records from which to derive the SET of values. |

expression | The expression from which to obtain the values, typically just a field in the recordset. |

UNORDERED | Optional. Specifies the output record order is not significant. |

ORDERED | Specifies the significance of the output record order. |

bool | When False, specifies the output record order is not significant. When True, specifies the default output record order. |

STABLE | Optional. Specifies the input record order is significant. |

UNSTABLE | Optional. Specifies the input record order is not significant. |

PARALLEL | Optional. Try to evaluate this activity in parallel. |

numthreads | Optional. Try to evaluate this activity using
numthreads threads. |

ALGORITHM | Optional. Override the algorithm used for this activity. |

name | The algorithm to use for this activity. Must be from the list of supported algorithms for the SORT function's STABLE and UNSTABLE options. |

Return: | SET returns a SET of values of the same type as the field. |

The **SET **function returns a SET for
use in any set operation (such as the IN operator), similar to a sub-select
in SQL when used with the IN operator. It does not remove duplicate elements
and does not order the set.

One common problem is the use of the SET function in a filter condition, like this:

`MyDS := myDataset(myField IN SET(anotherDataset, someField));`

The code generated for this is inefficient if "anotherDataset" contains a large number of elements, and may also cause a "Dataset too large to output to workunit" error. A better way to recode the expression would be this:

`MyDS := JOIN(myDataset, anotherDataset, LEFT.myField = RIGHT.someField, TRANSFORM(LEFT), LOOKUP) ;`

The end result is the same, the set of "myDataset" records where the "myField" value is one of the "someField" values from "anotherDataset," but the code is much more efficient in execution.

You can construct a DATASET from a SET.

```
ds := DATASET([{'X',1},{'B',3},{'C',2},{'B',5},
{'C',4},{'D',6},{'E',2}],
{STRING1 Ltr, INTEGER1 Val});
s1 := SET(ds,Ltr); //a SET of just the Ltr field values:
DATASET(s1,{STRING1 Ltr}); //a DATASET from the SET
```

Example:

```
ds := DATASET([{'X',1},{'B',3},{'C',2},{'B',5},
{'C',4},{'D',6},{'E',2}],
{STRING1 Ltr, INTEGER1 Val});
//a SET of just the Ltr field values:
s1 := SET(ds,Ltr);
COUNT(s1); //results in 7
OUTPUT(s1); //results in ['X','B','C','B','C','D','E']
//a simple way to get just the unique elements
//is to use a crosstab TABLE:
t := TABLE(ds,{Ltr},Ltr); //order indeterminant
s2 := SET(t,Ltr);
COUNT(s2); //results in 5
OUTPUT(s2); //results in ['D','X','C','E','B']
//sorted unique elements
s3 := SET(SORT(t,Ltr),Ltr);
COUNT(s3); //results in 5
OUTPUT(s3); //results in ['B','C','D','E','X']
//a SET of expression values:
s4 := SET(ds,Ltr+Val);
OUTPUT(s4); // results in ['X1','B3','C2','B5','C4','D6','E2']
```

See Also: Sets and Filters, SET OF, Set Operators, IN Operator