views:

135

answers:

2

I have a table with many fields and additionally several boolean fields (ex: BField1, BField2, BField3 etc.). I need to make a Select Query, which will select all fields except for boolean ones, and a new virtual field (ex: FirstTrueBool) whose value will equal to the name of the first TRUE Boolean Field.

For ex: Say I have BField1 = False, BField2 = True, BField3 = true, BField4=false, in that case SQL Query should set [FirstTrueBool] to "BField2". Is that possible?

Thank you in advance.

P.S. I use Microsoft Access (MDB) Database and Jet Engine.

+1  A: 

You would be better using a single 'int' column as a bitset (provided you have up to 32 columns) to represent the columns.

e.g. see SQL Server: Updating Integer Status Columns (it's sql server, but the same technique applies equally well to MS Access)

Mitch Wheat
Yes, I have figured out later, that it is a better option, but I have already done it the old way, and changing it would be painful :)
Tofig Hasanov
But then, a little pain now, might prevent alot of pain later....
Mitch Wheat
Still, I would need to put some kind of IF statement there. for example if value is 0101 then I want virtual field to be equal to "Field2", how can I implement that in SQL?
Tofig Hasanov
@Tofig Hasanov This may be of interest: http://sqlblog.com/blogs/denis_gobo/archive/2007/05/29/test.aspx
Remou
I would have said the structure was wrong, but the last solution I would have suggested was a bitset! There's repeating data, it belongs in another table in a N:1 relationship. Storing stuff in a field as a bitset is non-relational.
David-W-Fenton
+1  A: 

If you want to keep the current architecture (mixed 'x' non-null status and 'y' non-status fields) you have (AFAIS now) only the option to use IIF:

Select MyNonStatusField1, /* other non-status fields here */
  IIF([BField1], "BField1", 
  IIF([BField2], "BField2", 
...
  IIF([BFieldLast], "BFieldLast", "#No Flag#")
  ))))) -- put as many parenthesis as it needs to close the imbricated IIFs
From
  MyTable

Of course you can add any Where clause you like.


EDIT: Alternatively you can use the following trick: Set the fields to null when the flag is false and put the order number (iow, "1" for BField1, "2" for BField2 etc.) when the flag is true. Be sure that the status fields are strings (ie. Varchar(2) or, better, Char(2) in SQL terminology)

Then you can use the COALESCE function in order to return the first non-value from the status fields which will be the index number as string. Then you can add in front of this string any text you like (for example "BField"). Then you will end with something like:

Select "BField" || Coalesce(BField1, BField2, BField3, BField4) /*etc. (add as many fields you like) */
From MyTable

Much clearer IMHO.

HTH

Thanks, seems like a good solution to me!
Tofig Hasanov
What version of MS Access will this work with?
Remou
It worked with Access 2003 version of MDB for me, but I had one small problem, see http://stackoverflow.com/questions/2793980/parameter-xxx-has-no-default-value-error-when-using-order-by-in-sql-statement
Tofig Hasanov
Coalesce is not available in any version of Access AFAIK.
Remou
"Set the fields to null when the flag is false " - sure it's a solution, but that might trip someone up at a later date...
Mitch Wheat
Also, no version of Jet/ACE allows Boolean fields to be Null.
David-W-Fenton
I used the first solution, with IIFs.
Tofig Hasanov