2011-12-15 1 views
3

У меня есть битполя, называемое предупреждениями, хранящимися как int. Я хотел бы получить список предупреждений для каждого человекаРазбить строку на несколько строк с использованием столбца битполя в MySQL

позволяет сказать, что у нас есть таблица

NAME, WARNINGS 
alex, 0 
mike, 5 
sarah, 2 

, где каждый бит целого числа соответствует предупреждение # (битовой позиции). Это делается в настоящее время в Perl с петлей для

for(my $i=0; $i < $warning_size;$i++){ 
    if((1 << $i) & $warning != 0){ 
     print "$name\t" . $i+1 ."\n"; 
    } 
} 

Есть ли способ, что я могу это обрабатывается запрос MySQL.

Для приведенного выше примера, я хотел бы следующий вывод:

name, warning 
------------- 
mike 1 
mike 3 
sarah 2 

Я пытаюсь получить это вниз к одному отборного заявления,

Благодарности

+0

Вы уверены, что у вас нет опечатки в примере вывода? – ajreal

+0

нет, у меня нет опечатки. Проблема в том, что я не могу создать новые или временные таблицы. – Smartelf

+0

Можете ли вы объяснить, где находятся два микрофона? Вы вводите только показывать один mike. – ajreal

ответ

2

Попробуйте это один -

CREATE TABLE warn_bits(
    b INT(11) NOT NULL 
); 

INSERT INTO warn_bits VALUES 
    (1), 
    (2), 
    (3), 
    (4), 
    (5), 
    (6), 
    (7), 
    (8); 

SELECT w.name, wb.b FROM warnings w 
    JOIN warn_bits wb 
    ON ((w.WARNINGS >> wb.b - 1) & 1) > 0 
ORDER BY w.name, wb.b; 

+-------+---+ 
| name | b | 
+-------+---+ 
| mike | 1 | 
| mike | 3 | 
| sarah | 2 | 
+-------+---+ 

Вы можете расширить таблицу warn_bits для поддержки INT или BI GINT номера.


Edit2

SELECT w.name, wb.b FROM warnings w 
    JOIN (
    SELECT 1 b UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION 
    SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 
) wb 
    ON ((w.WARNINGS >> wb.b - 1) & 1) > 0 
ORDER BY w.name, wb.b; 
+0

Я не могу создать новые или временные таблицы, поэтому у меня так много проблем с этим. В любом случае, чтобы создать список значений в элементе select и псевдоним как таблицу, возможно, с sub_query? – Smartelf

+0

Конечно, вы можете присоединиться к нему как SELECT-запросы с UNION. – Devart

+0

Проверьте запрос «Редактировать2». – Devart

0

Сделать временную таблицу для битового дробления.

mysql> create table bitcrush(bit int); 
Query OK, 0 rows affected (0.02 sec) 

mysql> insert into bitcrush values (1),(2),(4),(8),(16),(32),(64),(128),(256); 
Query OK, 8 rows affected (0.01 sec) 
Records: 8 Duplicates: 0 Warnings: 0 

mysql> select name, log2(bit)+1 as warn from c821885 join bitcrush on warn & bit order by name; 
+-------+------+ 
| name | warn | 
+-------+------+ 
| mike | 1 | 
| mike | 3 | 
| sarah | 2 | 
+-------+------+ 
3 rows in set (0.00 sec) 
0

Я думаю, вы просто ищете power(2, x);, попробуйте следующее: -

 
mysql> select length(conv(0, 10, 2)); 
+------------------------+ 
| length(conv(0, 10, 2)) | 
+------------------------+ 
|      1 | 
+------------------------+ 
1 row in set (0.00 sec) 

mysql> select length(conv(2, 10, 2)); 
+------------------------+ 
| length(conv(2, 10, 2)) | 
+------------------------+ 
|      2 | 
+------------------------+ 
1 row in set (0.00 sec) 

mysql> select length(conv(5, 10, 2)); 
+------------------------+ 
| length(conv(5, 10, 2)) | 
+------------------------+ 
|      3 | 
+------------------------+ 
1 row in set (0.00 sec) 
0

Если вы нормально с наличием колонки на предупреждение можно также использовать export_set() и подстроку() для разбить биты.

Я собираюсь предположить, что вы используете 4 бита.

bit 1 = "fatal" 
bit 2 = "warning" 
bit 3 = "error" 
bit 4 = "user error" 

SELECT 
name, 
EXPORT_SET(warning,1,0,'',4) AS debugBits, 
SUBSTRING(EXPORT_SET(warning,1,0,'',4),1,1) AS hasFatal, 
SUBSTRING(EXPORT_SET(warning,1,0,'',4),2,1) AS hasWarning, 
SUBSTRING(EXPORT_SET(warning,1,0,'',4),3,1) AS hasError, 
SUBSTRING(EXPORT_SET(warning,1,0,'',4),4,1) AS hasUserError 
FROM warnings; 

, который должен вывести что-то вроде:

------|----------|---------|-----------|---------|-------------| 
name |debugBits | hasFatal| hasWarning| hasError| hasUserError| 
alex |  0000|  0|   0|  0|   0| 
mike |  1010|  1|   0|  1|   0| 
sarah |  0010|  0|   0|  1|   0| 
------|----------|---------|-----------|---------|-------------| 

Обратите внимание, что export_set (дисплеи) бит 1 в крайнее левое положение. http://dev.mysql.com/doc/refman/5.5/en/string-functions.html#function_export-set

Если вы нормально с колонкой CSV для предупреждения, вы могли бы использовать make_set()

SELECT 
name, 
MAKE_SET(warning, 
'fatal', 
'warning', 
'error', 
'userError') AS warningText 
FROM warnings 

который получит вам один столбец для предупреждений со списком CSV из набора битовых меток. http://dev.mysql.com/doc/refman/5.5/en/string-functions.html#function_make-set

Смежные вопросы