[英]Sql Server, how can I identify a result column so I can use it in a where clause
[英]How can I apply a logical OR to a BINARY column so the result is all the correct values?
我有一組存儲在 binary(12) 列中的結果。 我正在尋找針對特定條件在不同時間設置的所有標志。 它就像
地位 | 標志 |
---|---|
1234 | 0x000000000000000000002000 |
5678 | 0x0000000000000000000000000 |
1234 | 0x0000000000000000000000040 |
我想做的是寫一個查詢,例如
SELECT Status, OR(Flags)
FROM StatusTable
GROUP BY Status
給出結果
地位 | 或(標志) |
---|---|
1234 | 0x0000000000000000000002040 |
5678 | 0x0000000000000000000000000 |
我可以找到讓我手動 OR 兩個值但沒有將 OR 應用於結果列的示例。 我已經大大簡化了這個例子,但我們正在談論數千個具有數千個狀態的值(主要是 0x000000000000000000000000),這使得手動或它們是不切實際的。 我想可以使用 function 和 cursor 來循環每個,但肯定有一個開箱即用的解決方案嗎?
在 TSQL 中寫這個很難,如果你不能修復底層設計,你可以寫一個.Net CLR 用戶定義的聚合。
在 C# 中,您有二進制 OR 運算符: 按位和移位運算符。
您可以按照本指南編寫 CLR function: CLR User-Defined Aggregates
T-SQL 不擅長處理比特。 但它確實有&
和|
. 您需要分解每個標志,將其匯總在表格上,然后將其重新打包
由於缺少二進制STRING_AGG
,這個查詢並沒有變得更容易。
SELECT
[Status],
CAST(SUM(CASE WHEN byte = 1 THEN val END) AS binary(4)) +
CAST(SUM(CASE WHEN byte = 5 THEN val END) AS binary(4)) +
CAST(SUM(CASE WHEN byte = 9 THEN val END) AS binary(4)) AS OrFlags
FROM (
SELECT [Status], v1.bytePos,
MAX(CASE WHEN CAST(SUBSTRING(Flags, v1.bytePos, 4) AS int) & v2.bitt <> 0 THEN v2.bitt ELSE 0 END) AS val
FROM @StatusTable
CROSS JOIN (VALUES(1),(5),(9)) v1(bytePos)
CROSS JOIN (VALUES
(1),(2),(4),(8),(16),(32),(64),(128),(256),(512),(1024),(2048),(4096),(8192),(16384),(32768),(65536),(131072),(262144),(524288),(1048576),(2097152),(4194304),(8388608),(16777216),(33554432),(67108864),(134217728),(268435456),(536870912),(1073741824),(-2147483648)
) v2(bitt)
GROUP BY [Status], v1.bytePos, v2.bitt
) t
GROUP BY Status
步驟如下:
1,5,9
起始字節數。Status
和位置/標志分組Status
,Integer position,以及是否有任何值設置了這個標志如果要實現AND
聚合,請將MAX
更改為MIN
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.