Преобразовать целое число в список дней недели
-
03-07-2019 - |
Вопрос
У меня есть целое число, хранящееся в базе данных (интервал частоты SQLAgent), Это целое число фактически является суммой выбранных дней недели, в которые должно выполняться расписание Возможными значениями являются любые комбинации этих значений
- Воскресенье =1
- Понедельник = 2
- Вторник =4
- Среда= 8
- Четверг = 16
- Пятница = 32
- Суббота =64
пример 65 означает, что расписание должно выполняться в субботу и воскресенье
Моя проблема в том, что мне нужно представить эти значения в виде текста "Суббота" и "Воскресенье", когда задано 65, и я пытаюсь сделать это в SQL
Кроме огромного заявления CASE со всеми возможными комбинациями, кто-нибудь может придумать способ сделать это?
Спасибо
Решение
Вы можете использовать побитовые операторы в T-SQL.Вот как это делается:
SELECT
( CASE WHEN daybits & 1 = 1 THEN 'Sunday ' ELSE '' END ) +
( CASE WHEN daybits & 2 = 2 THEN 'Monday ' ELSE '' END ) +
( CASE WHEN daybits & 4 = 4 THEN 'Tuesday ' ELSE '' END ) +
...
( CASE WHEN daybits & 64 = 64 THEN 'Saturday ' ELSE '' END ) +
Это приведет, например, к появлению "Sunday Saturday".
Другие советы
Я бы начал с того, что поместил его в определяемую пользователем функцию.Кроме того, вы можете использовать and, который работает на битовом уровне, чтобы проверить это - я думаю, что это &, обновится.
Обновление 1: Это было &, Джейсон уже приводил пример.Я по-прежнему рекомендую использовать для этого пользовательскую функцию :).
Редактировать:Это код на C # для выполнения битовых операций.Я опубликовал его перед подробным прочтением вопроса, но я оставлю его здесь в качестве альтернативы.Действительно ли база данных - лучшее место для этого ...?
Вы можете использовать массив:
// input: int value
string[] weekdays = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Saturday" };
int flag = 1
List<string> days = new List<string>();
foreach (string day in days) {
if ((value && flag) != 0) {
days.Add(day);
}
flag <<= 1;
}
Результатом является список строк, если вы хотите объединить их, вы можете, например, сделать:
string selected = String.Join(", ", days.ToArray());
DECLARE @in INTEGER;
SET @in = 63;
WITH series(n) AS
(
SELECT 0
UNION ALL
SELECT n + 1
FROM series
WHERE n < 6
)
SELECT CASE WHEN ROW_NUMBER() OVER (ORDER BY n) > 1 THEN ', ' ELSE '' END + DATENAME(weekday, DATEADD(day, n, '1980-09-03'))
FROM series
WHERE (POWER(2, n) & @in) > 0
ORDER BY n
FOR XML PATH ('')