If you like @BillKarwin’s suggestion, I would add that you can then consider using the following **single‑row views** method, which simulates **enum‑like** behaviour in T‑SQL, if you need it in your SQL module code. Also, when using a lookup table, you can add additional attributes to it as needed.
```
SELECT o.*
FROM dbo.Orders o
-- "enum" views
CROSS JOIN dbo.en_OrderStatus s
CROSS JOIN dbo.en_DeliveryType t
WHERE
(
o.OrderStatusID IN (s.Pending, s.Processing)
AND
o.OrderStatusID NOT IN (s.Shipped, s.Delivered)
)
OR o.DeliveryTypeID = t.Mail;
```
If you like the way it is used, I wrote an article about this method where you can find more details on how to implement it: <https://www.sqlservercentral.com/articles/sql-server-enum-implementation-a-single-row-view-strategy-for-avoiding-magic-values>
Some additional information that is not in the article - because of view expansion and constant folding, the optimizer will always embed the constants directly into the execution tree and eliminate the CROSS JOIN. *At some point I will update the article with a more precise explanation, including the note that the best way to create these views is by using the SCHEMABINDING option, which is missing in the original article.* 🙂
I would also agree with the suggestion to properly normalize your model and add a lookup table containing all other necessary attributes, and then use the following **single‑row views** method that simulates **enum‑like behaviour** in T‑SQL. You can use it in SQL modules like this:
```
SELECT o.*
FROM dbo.Orders o
-- "enum" views
CROSS JOIN dbo.en_OrderStatus s
CROSS JOIN dbo.en_DeliveryType t
WHERE
(
o.OrderStatusID IN (s.Pending, s.Processing)
AND
o.OrderStatusID NOT IN (s.Shipped, s.Delivered)
)
OR o.DeliveryTypeID = t.Mail;
```
If you like the way it is used, I wrote an article about this method where you can find more details on how to implement it: <https://www.sqlservercentral.com/articles/sql-server-enum-implementation-a-single-row-view-strategy-for-avoiding-magic-values>
Some additional information that is not in the article - because of view expansion and constant folding, the optimizer will always embed the constants directly into the execution tree and eliminate the CROSS JOIN. *At some point I will update the article with a more precise explanation, including the note that the best way to create these views is by using the SCHEMABINDING option, which is missing in the original article.* 🙂