2012-09-17 24 views
2

我在想如果在T-SQL中確定二進制值中的最大數字是否存在短路(而不編程整個事物)。如何確定按位值中的最大位

在一列中,我存儲按位選擇幾天(1 = sunday, 2 = monday, .. 7 = saturday)。

我的翻譯表:

-- day of week 
-- 1 == 1  -> POWER(2,0) -> sunday 
-- 2 == 2  -> POWER(2,1) -> monday 
-- 3 == 4  -> POWER(2,2) 
-- 4 == 8  -> POWER(2,3) 
-- 5 == 16  -> POWER(2,4) 
-- 6 == 32  -> POWER(2,5) 
-- 7 == 64  -> POWER(2,6) -> saturday 

所以,如果我選擇FOR EXAMPLE週日,上星期六,我的二進制值是65

如何我可以T-SQL65選擇將是7


編輯

比方說,我有兩個記錄與兩列:

ID | SelectedDays 
------|-------------- 
1 | 65 
2 | 3 

所以,ID 1將回到7,因爲這將是選擇選擇和週六ID 2將於週一返回。

+0

你想某種基於集合的解決方案或是一個時間/光標好嗎? – JonH

+0

拆分你的組合列,並使每一天都有自己的單一位列 –

+0

@JonH嗯,理想情況下,我想寫儘可能少的代碼 – 321X

回答

6
SELECT FLOOR(LOG(bit_week)/LOG(2))+1 

這將返回1到7根據日期。
logaritmpower與基數2中的方框對數的倒數,訣竅是「除以基數」。 FLOOR反過來提供最有意義的位。

+0

就是這樣!非常感謝! – 321X

+0

請參閱@GilM anwser也 –

+1

這是非常好的,但我想你想添加1的結果來獲得星期值(1-7),而不是log2值(0-6) – GilM

0

如果你只是週六

select * from table where dayOfWeek >= 64 
+0

不可行,我需要知道選擇的最大日期 – 321X

+0

@ 321X,然後請顯示一些樣本數據和期望的結果。 –

+0

已添加信息 – 321X

1

尋找所有的值在C#中,你可以做類似下面

 int i = 65; 
     var b = Convert.ToString(i, 2).PadLeft(8, '0'); //pad to 8 bit binary 
     var c = Math.Pow(2, 7 - b.IndexOf("1")); 

--------遺憾無緣編輯------

var c = Enumerable.Range(0, b.Length).Where(x=>b[x] == '1').ToArray(); 
+0

現在確定C#答案是不允許的。 –

+0

非常感謝C#輸入!本來我只是在尋找一個T-SQL解決方案,然後我改變了主意。在收到大量SQL響應之後,我再次改變了主意! :-) – 321X

1

如果你聲明你的枚舉爲標誌,那麼使用它可以直接使用它,而不用任何minupulation在SQL側,只要你在INT列存儲..

[Flags] 
enum Day 
{ 
    Sunday =1, 
    Monday, 
    Tuesday 
    .... 
    Saturday 
} 

var day = Day.Sunday | Day.Saturday //Internally enum will have bit flags set for 65. 

您可以插入DB這個值作爲整數。

要加載它,只需加載day的值並設置枚舉。 SQL中不需要做任何事情;只是SELECT Day FROM MyTable

在你的C#

//Sample query for retrieving 
Day day = (Day)db.ExecuteScalar("SELECT Day FROM MyTable WHERE ID = 'someid'"); 
+0

感謝您的提示!我從來沒有想過以這種方式使用枚舉 – 321X

1

POWER()的計算結果是通過功率(1/2)的倒數來計算的。 例如: (對於週一,週三,週五= 2 + 8 + 32 = 42) 反向功率爲POWER(42.0,(1.0/2.0))= 6.5。截斷小數給你6.(星期五)。

SELECT Convert(int,power(Convert(Decimal,SelectedDays),0。5))

4

在SQL Server 2012中,你可以使用第二個參數,以獲得數底2的值,所以我覺得你一週中的一天將是:

FLOOR(LOG(binarycolumn,2)+1) 

如果沒有,你可以做一些缺憾像:

CASE WHEN BinaryColumn >=64 THEN 7 
    WHEN BinaryColumn >=32 THEN 6 
    WHEN BinaryColumn >=16 THEN 5 
    WHEN BinaryColumn >=8 THEN 4 
    WHEN BinaryColumn >=4 THEN 3 
    WHEN BinaryColumn >=1 THEN 2 
    ELSE      1 
    END 
+0

感謝您的選擇,但'CASE WHEN'將比我假設的一些數學運算花費更多 – 321X