sql save month boolean fields as integer for bitwise manipulation
up vote
1
down vote
favorite
Probably overthinking this. Issue is I've inherited a database where a member can have two (or more) addresses as part of membership (think seasonal) record (addresses are in separate records), and database actions depend on which address the member is currently located at.
Currently, each month (Jan, Feb, etc.) is a bit field. So in order to query where a member is this month (or span of months) you have to either select for the field name that matches current month (or month span for period), meaning you have to query by variable field name... or scan through the 12 fields - clumsy. Seems to me it should either be an integer field that is queried by bitwise xor operation (one for which months are flagged and one for query period), or by "adding" the field values into a string of bits converted to integer number then using bitwise comparison.
Second option would be ok (wouldn't change the table structure) but would rather use one integer field to represent a binary version of the 12 months then work with that.
In either case, been way too many years since I did much bitwise work, much less figure out how to convert into binary representation. I expect there is already a published answer somewhere, but can't find it. Any suggestions? Thanks!
add a comment |
up vote
1
down vote
favorite
Probably overthinking this. Issue is I've inherited a database where a member can have two (or more) addresses as part of membership (think seasonal) record (addresses are in separate records), and database actions depend on which address the member is currently located at.
Currently, each month (Jan, Feb, etc.) is a bit field. So in order to query where a member is this month (or span of months) you have to either select for the field name that matches current month (or month span for period), meaning you have to query by variable field name... or scan through the 12 fields - clumsy. Seems to me it should either be an integer field that is queried by bitwise xor operation (one for which months are flagged and one for query period), or by "adding" the field values into a string of bits converted to integer number then using bitwise comparison.
Second option would be ok (wouldn't change the table structure) but would rather use one integer field to represent a binary version of the 12 months then work with that.
In either case, been way too many years since I did much bitwise work, much less figure out how to convert into binary representation. I expect there is already a published answer somewhere, but can't find it. Any suggestions? Thanks!
add a comment |
up vote
1
down vote
favorite
up vote
1
down vote
favorite
Probably overthinking this. Issue is I've inherited a database where a member can have two (or more) addresses as part of membership (think seasonal) record (addresses are in separate records), and database actions depend on which address the member is currently located at.
Currently, each month (Jan, Feb, etc.) is a bit field. So in order to query where a member is this month (or span of months) you have to either select for the field name that matches current month (or month span for period), meaning you have to query by variable field name... or scan through the 12 fields - clumsy. Seems to me it should either be an integer field that is queried by bitwise xor operation (one for which months are flagged and one for query period), or by "adding" the field values into a string of bits converted to integer number then using bitwise comparison.
Second option would be ok (wouldn't change the table structure) but would rather use one integer field to represent a binary version of the 12 months then work with that.
In either case, been way too many years since I did much bitwise work, much less figure out how to convert into binary representation. I expect there is already a published answer somewhere, but can't find it. Any suggestions? Thanks!
Probably overthinking this. Issue is I've inherited a database where a member can have two (or more) addresses as part of membership (think seasonal) record (addresses are in separate records), and database actions depend on which address the member is currently located at.
Currently, each month (Jan, Feb, etc.) is a bit field. So in order to query where a member is this month (or span of months) you have to either select for the field name that matches current month (or month span for period), meaning you have to query by variable field name... or scan through the 12 fields - clumsy. Seems to me it should either be an integer field that is queried by bitwise xor operation (one for which months are flagged and one for query period), or by "adding" the field values into a string of bits converted to integer number then using bitwise comparison.
Second option would be ok (wouldn't change the table structure) but would rather use one integer field to represent a binary version of the 12 months then work with that.
In either case, been way too many years since I did much bitwise work, much less figure out how to convert into binary representation. I expect there is already a published answer somewhere, but can't find it. Any suggestions? Thanks!
asked Nov 8 at 17:21
Ben
62
62
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
up vote
0
down vote
Since you are open to using an integer field, add a column to your table to hold the month numeric values.
alter table myTable
add column MonthNum int
alter table myTable
add constraint CK_Month_Range CHECK (MonthNum > 0 and MonthNum < 13)
There wouldn't be any benefit of storing a bit representation of the month number in an integer field since the same amount of space will be taken up (4 bytes). Many system table use bitwise values but in this case, I don't see how it would improve anything.
In order to check if they are there, I would probably do one of two things.
- Use a
bitvalue column for IsCurrent - Use a form of row versioning where the last updated datetime would be the current record
Here is a bitwise type of check if your application will send in an integer for the parameter
declare @table table (id int identity(1,1), jan bit, feb bit, mar bit, apr bit, may bit, jun bit, jul bit, aug bit, sep bit, oct bit, nov bit, [dec] bit)
insert into @table
values
(0,0,0,0,0,0,0,1,0,0,0,0), --aug
(0,0,1,0,0,0,0,0,0,0,0,0), --mar
(0,0,0,0,0,0,0,0,0,0,0,1), --dec
(1,0,0,0,0,0,0,0,0,0,0,0) --jan
declare @month int = 3
select *, bitwise = concat(jan,feb,mar,apr,may,jun,jul,aug,sep,oct,nov,[dec])
from @table
where charindex('1',concat(jan,feb,mar,apr,may,jun,jul,aug,sep,oct,nov,[dec])) = @month
If they are passing in strings, like 'January', then you'd just join to a lookup table.
The current structure works fine for some things. The issue gets into needing to find those records that meet the criteria of being true in one or more months (usually one) for reporting. Yes, I can hand code a query that creates a temp table for a specific month, BUT I would like to be able to query for that month field that matches the month being worked - i.e., if it's November, I need to see which member address record is in the month of November as a passed variable to the query, NOT by passing a hard coded month name value. Hope that makes sense...
– Ben
Nov 9 at 1:28
What values are in the month column? Can you provide sample data?
– scsimon
Nov 9 at 2:08
there are 12 month fields (columns), each named for the month (Jan, Feb, Mar, etc.). The field is a bit field, values are 0 and 1 - boolean.
– Ben
Nov 11 at 19:40
Oh your data is pivoted and unnormalized then. You should fix that
– scsimon
Nov 11 at 19:59
Well, not really, since the Month fields are not used EXCEPT for a couple of reports monthly. Creating a record for each month is a bit drastic for an address record! What I would prefer is using an integer for bitwise manipulation for - i.e, 12 binary places, one for each month, 0 for no, 1 for yes, with the address records having one field for that integer. Then do an xor of the report date (converted to integer) to get a result that tells the report to use that address record for the reporting date. Alternate would be to concatenate the 12 month bits into a number for the comparison.
– Ben
Nov 12 at 20:09
|
show 4 more comments
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
0
down vote
Since you are open to using an integer field, add a column to your table to hold the month numeric values.
alter table myTable
add column MonthNum int
alter table myTable
add constraint CK_Month_Range CHECK (MonthNum > 0 and MonthNum < 13)
There wouldn't be any benefit of storing a bit representation of the month number in an integer field since the same amount of space will be taken up (4 bytes). Many system table use bitwise values but in this case, I don't see how it would improve anything.
In order to check if they are there, I would probably do one of two things.
- Use a
bitvalue column for IsCurrent - Use a form of row versioning where the last updated datetime would be the current record
Here is a bitwise type of check if your application will send in an integer for the parameter
declare @table table (id int identity(1,1), jan bit, feb bit, mar bit, apr bit, may bit, jun bit, jul bit, aug bit, sep bit, oct bit, nov bit, [dec] bit)
insert into @table
values
(0,0,0,0,0,0,0,1,0,0,0,0), --aug
(0,0,1,0,0,0,0,0,0,0,0,0), --mar
(0,0,0,0,0,0,0,0,0,0,0,1), --dec
(1,0,0,0,0,0,0,0,0,0,0,0) --jan
declare @month int = 3
select *, bitwise = concat(jan,feb,mar,apr,may,jun,jul,aug,sep,oct,nov,[dec])
from @table
where charindex('1',concat(jan,feb,mar,apr,may,jun,jul,aug,sep,oct,nov,[dec])) = @month
If they are passing in strings, like 'January', then you'd just join to a lookup table.
The current structure works fine for some things. The issue gets into needing to find those records that meet the criteria of being true in one or more months (usually one) for reporting. Yes, I can hand code a query that creates a temp table for a specific month, BUT I would like to be able to query for that month field that matches the month being worked - i.e., if it's November, I need to see which member address record is in the month of November as a passed variable to the query, NOT by passing a hard coded month name value. Hope that makes sense...
– Ben
Nov 9 at 1:28
What values are in the month column? Can you provide sample data?
– scsimon
Nov 9 at 2:08
there are 12 month fields (columns), each named for the month (Jan, Feb, Mar, etc.). The field is a bit field, values are 0 and 1 - boolean.
– Ben
Nov 11 at 19:40
Oh your data is pivoted and unnormalized then. You should fix that
– scsimon
Nov 11 at 19:59
Well, not really, since the Month fields are not used EXCEPT for a couple of reports monthly. Creating a record for each month is a bit drastic for an address record! What I would prefer is using an integer for bitwise manipulation for - i.e, 12 binary places, one for each month, 0 for no, 1 for yes, with the address records having one field for that integer. Then do an xor of the report date (converted to integer) to get a result that tells the report to use that address record for the reporting date. Alternate would be to concatenate the 12 month bits into a number for the comparison.
– Ben
Nov 12 at 20:09
|
show 4 more comments
up vote
0
down vote
Since you are open to using an integer field, add a column to your table to hold the month numeric values.
alter table myTable
add column MonthNum int
alter table myTable
add constraint CK_Month_Range CHECK (MonthNum > 0 and MonthNum < 13)
There wouldn't be any benefit of storing a bit representation of the month number in an integer field since the same amount of space will be taken up (4 bytes). Many system table use bitwise values but in this case, I don't see how it would improve anything.
In order to check if they are there, I would probably do one of two things.
- Use a
bitvalue column for IsCurrent - Use a form of row versioning where the last updated datetime would be the current record
Here is a bitwise type of check if your application will send in an integer for the parameter
declare @table table (id int identity(1,1), jan bit, feb bit, mar bit, apr bit, may bit, jun bit, jul bit, aug bit, sep bit, oct bit, nov bit, [dec] bit)
insert into @table
values
(0,0,0,0,0,0,0,1,0,0,0,0), --aug
(0,0,1,0,0,0,0,0,0,0,0,0), --mar
(0,0,0,0,0,0,0,0,0,0,0,1), --dec
(1,0,0,0,0,0,0,0,0,0,0,0) --jan
declare @month int = 3
select *, bitwise = concat(jan,feb,mar,apr,may,jun,jul,aug,sep,oct,nov,[dec])
from @table
where charindex('1',concat(jan,feb,mar,apr,may,jun,jul,aug,sep,oct,nov,[dec])) = @month
If they are passing in strings, like 'January', then you'd just join to a lookup table.
The current structure works fine for some things. The issue gets into needing to find those records that meet the criteria of being true in one or more months (usually one) for reporting. Yes, I can hand code a query that creates a temp table for a specific month, BUT I would like to be able to query for that month field that matches the month being worked - i.e., if it's November, I need to see which member address record is in the month of November as a passed variable to the query, NOT by passing a hard coded month name value. Hope that makes sense...
– Ben
Nov 9 at 1:28
What values are in the month column? Can you provide sample data?
– scsimon
Nov 9 at 2:08
there are 12 month fields (columns), each named for the month (Jan, Feb, Mar, etc.). The field is a bit field, values are 0 and 1 - boolean.
– Ben
Nov 11 at 19:40
Oh your data is pivoted and unnormalized then. You should fix that
– scsimon
Nov 11 at 19:59
Well, not really, since the Month fields are not used EXCEPT for a couple of reports monthly. Creating a record for each month is a bit drastic for an address record! What I would prefer is using an integer for bitwise manipulation for - i.e, 12 binary places, one for each month, 0 for no, 1 for yes, with the address records having one field for that integer. Then do an xor of the report date (converted to integer) to get a result that tells the report to use that address record for the reporting date. Alternate would be to concatenate the 12 month bits into a number for the comparison.
– Ben
Nov 12 at 20:09
|
show 4 more comments
up vote
0
down vote
up vote
0
down vote
Since you are open to using an integer field, add a column to your table to hold the month numeric values.
alter table myTable
add column MonthNum int
alter table myTable
add constraint CK_Month_Range CHECK (MonthNum > 0 and MonthNum < 13)
There wouldn't be any benefit of storing a bit representation of the month number in an integer field since the same amount of space will be taken up (4 bytes). Many system table use bitwise values but in this case, I don't see how it would improve anything.
In order to check if they are there, I would probably do one of two things.
- Use a
bitvalue column for IsCurrent - Use a form of row versioning where the last updated datetime would be the current record
Here is a bitwise type of check if your application will send in an integer for the parameter
declare @table table (id int identity(1,1), jan bit, feb bit, mar bit, apr bit, may bit, jun bit, jul bit, aug bit, sep bit, oct bit, nov bit, [dec] bit)
insert into @table
values
(0,0,0,0,0,0,0,1,0,0,0,0), --aug
(0,0,1,0,0,0,0,0,0,0,0,0), --mar
(0,0,0,0,0,0,0,0,0,0,0,1), --dec
(1,0,0,0,0,0,0,0,0,0,0,0) --jan
declare @month int = 3
select *, bitwise = concat(jan,feb,mar,apr,may,jun,jul,aug,sep,oct,nov,[dec])
from @table
where charindex('1',concat(jan,feb,mar,apr,may,jun,jul,aug,sep,oct,nov,[dec])) = @month
If they are passing in strings, like 'January', then you'd just join to a lookup table.
Since you are open to using an integer field, add a column to your table to hold the month numeric values.
alter table myTable
add column MonthNum int
alter table myTable
add constraint CK_Month_Range CHECK (MonthNum > 0 and MonthNum < 13)
There wouldn't be any benefit of storing a bit representation of the month number in an integer field since the same amount of space will be taken up (4 bytes). Many system table use bitwise values but in this case, I don't see how it would improve anything.
In order to check if they are there, I would probably do one of two things.
- Use a
bitvalue column for IsCurrent - Use a form of row versioning where the last updated datetime would be the current record
Here is a bitwise type of check if your application will send in an integer for the parameter
declare @table table (id int identity(1,1), jan bit, feb bit, mar bit, apr bit, may bit, jun bit, jul bit, aug bit, sep bit, oct bit, nov bit, [dec] bit)
insert into @table
values
(0,0,0,0,0,0,0,1,0,0,0,0), --aug
(0,0,1,0,0,0,0,0,0,0,0,0), --mar
(0,0,0,0,0,0,0,0,0,0,0,1), --dec
(1,0,0,0,0,0,0,0,0,0,0,0) --jan
declare @month int = 3
select *, bitwise = concat(jan,feb,mar,apr,may,jun,jul,aug,sep,oct,nov,[dec])
from @table
where charindex('1',concat(jan,feb,mar,apr,may,jun,jul,aug,sep,oct,nov,[dec])) = @month
If they are passing in strings, like 'January', then you'd just join to a lookup table.
edited Nov 12 at 20:25
answered Nov 8 at 17:34
scsimon
19.9k41536
19.9k41536
The current structure works fine for some things. The issue gets into needing to find those records that meet the criteria of being true in one or more months (usually one) for reporting. Yes, I can hand code a query that creates a temp table for a specific month, BUT I would like to be able to query for that month field that matches the month being worked - i.e., if it's November, I need to see which member address record is in the month of November as a passed variable to the query, NOT by passing a hard coded month name value. Hope that makes sense...
– Ben
Nov 9 at 1:28
What values are in the month column? Can you provide sample data?
– scsimon
Nov 9 at 2:08
there are 12 month fields (columns), each named for the month (Jan, Feb, Mar, etc.). The field is a bit field, values are 0 and 1 - boolean.
– Ben
Nov 11 at 19:40
Oh your data is pivoted and unnormalized then. You should fix that
– scsimon
Nov 11 at 19:59
Well, not really, since the Month fields are not used EXCEPT for a couple of reports monthly. Creating a record for each month is a bit drastic for an address record! What I would prefer is using an integer for bitwise manipulation for - i.e, 12 binary places, one for each month, 0 for no, 1 for yes, with the address records having one field for that integer. Then do an xor of the report date (converted to integer) to get a result that tells the report to use that address record for the reporting date. Alternate would be to concatenate the 12 month bits into a number for the comparison.
– Ben
Nov 12 at 20:09
|
show 4 more comments
The current structure works fine for some things. The issue gets into needing to find those records that meet the criteria of being true in one or more months (usually one) for reporting. Yes, I can hand code a query that creates a temp table for a specific month, BUT I would like to be able to query for that month field that matches the month being worked - i.e., if it's November, I need to see which member address record is in the month of November as a passed variable to the query, NOT by passing a hard coded month name value. Hope that makes sense...
– Ben
Nov 9 at 1:28
What values are in the month column? Can you provide sample data?
– scsimon
Nov 9 at 2:08
there are 12 month fields (columns), each named for the month (Jan, Feb, Mar, etc.). The field is a bit field, values are 0 and 1 - boolean.
– Ben
Nov 11 at 19:40
Oh your data is pivoted and unnormalized then. You should fix that
– scsimon
Nov 11 at 19:59
Well, not really, since the Month fields are not used EXCEPT for a couple of reports monthly. Creating a record for each month is a bit drastic for an address record! What I would prefer is using an integer for bitwise manipulation for - i.e, 12 binary places, one for each month, 0 for no, 1 for yes, with the address records having one field for that integer. Then do an xor of the report date (converted to integer) to get a result that tells the report to use that address record for the reporting date. Alternate would be to concatenate the 12 month bits into a number for the comparison.
– Ben
Nov 12 at 20:09
The current structure works fine for some things. The issue gets into needing to find those records that meet the criteria of being true in one or more months (usually one) for reporting. Yes, I can hand code a query that creates a temp table for a specific month, BUT I would like to be able to query for that month field that matches the month being worked - i.e., if it's November, I need to see which member address record is in the month of November as a passed variable to the query, NOT by passing a hard coded month name value. Hope that makes sense...
– Ben
Nov 9 at 1:28
The current structure works fine for some things. The issue gets into needing to find those records that meet the criteria of being true in one or more months (usually one) for reporting. Yes, I can hand code a query that creates a temp table for a specific month, BUT I would like to be able to query for that month field that matches the month being worked - i.e., if it's November, I need to see which member address record is in the month of November as a passed variable to the query, NOT by passing a hard coded month name value. Hope that makes sense...
– Ben
Nov 9 at 1:28
What values are in the month column? Can you provide sample data?
– scsimon
Nov 9 at 2:08
What values are in the month column? Can you provide sample data?
– scsimon
Nov 9 at 2:08
there are 12 month fields (columns), each named for the month (Jan, Feb, Mar, etc.). The field is a bit field, values are 0 and 1 - boolean.
– Ben
Nov 11 at 19:40
there are 12 month fields (columns), each named for the month (Jan, Feb, Mar, etc.). The field is a bit field, values are 0 and 1 - boolean.
– Ben
Nov 11 at 19:40
Oh your data is pivoted and unnormalized then. You should fix that
– scsimon
Nov 11 at 19:59
Oh your data is pivoted and unnormalized then. You should fix that
– scsimon
Nov 11 at 19:59
Well, not really, since the Month fields are not used EXCEPT for a couple of reports monthly. Creating a record for each month is a bit drastic for an address record! What I would prefer is using an integer for bitwise manipulation for - i.e, 12 binary places, one for each month, 0 for no, 1 for yes, with the address records having one field for that integer. Then do an xor of the report date (converted to integer) to get a result that tells the report to use that address record for the reporting date. Alternate would be to concatenate the 12 month bits into a number for the comparison.
– Ben
Nov 12 at 20:09
Well, not really, since the Month fields are not used EXCEPT for a couple of reports monthly. Creating a record for each month is a bit drastic for an address record! What I would prefer is using an integer for bitwise manipulation for - i.e, 12 binary places, one for each month, 0 for no, 1 for yes, with the address records having one field for that integer. Then do an xor of the report date (converted to integer) to get a result that tells the report to use that address record for the reporting date. Alternate would be to concatenate the 12 month bits into a number for the comparison.
– Ben
Nov 12 at 20:09
|
show 4 more comments
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53213039%2fsql-save-month-boolean-fields-as-integer-for-bitwise-manipulation%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown