0

Excel ではなく mysql で情報を収集しています。細胞タイプごとにいくつかのラベルが定義されており、すべてのラベルが存在するわけではありません。したがって、3 つのラベル、情報、およびセル テーブルがあります。

select cell_name, label, information from onco_celldb_information as info 
left join onco_celldb_cells as cell on cell.`celldb_cell_id` = info.`celldb_cell_id`
left join onco_celldb_labels as label on info.`celldb_label_id` = label.`celldb_label_id`
order by cell.celldb_cell_id asc;

結果は次のようになります。

上記のクエリを実行 http://f.cl.ly/items/0m2k1a410s3D0K2Y0l1u/Screen%20Shot%202012-08-22%20at%2011.57.36%20AM.png

しかし、私が欲しいのは次のようなものです:

CellName    Species     CellType    Origin
---------+-----------+-----------+-----------
P-815      Murine      Mastroxxxx    Human
L292      Something      Megatrone    Mouse

したがって、それらをセル名でグループ化し、結果を列として表示します。ラベルが存在しない場合は、そこに NULL があります (一部の結果にはラベルが存在しない場合があります)。

何を指示してるんですか?

データベース構造で編集:

mysql> describe celldb_cells;
+----------------+------------------+------+-----+---------+----------------+
| Field          | Type             | Null | Key | Default | Extra          |
+----------------+------------------+------+-----+---------+----------------+
| celldb_cell_id | int(11) unsigned | NO   | PRI | NULL    | auto_increment |
| cell_name      | varchar(256)     | YES  |     | NULL    |                |
+----------------+------------------+------+-----+---------+----------------+

describe celldb_information;
+-----------------------+------------------+------+-----+---------+----------------+
| Field                 | Type             | Null | Key | Default | Extra          |
+-----------------------+------------------+------+-----+---------+----------------+
| celldb_information_id | int(11) unsigned | NO   | PRI | NULL    | auto_increment |
| celldb_cell_id        | int(11) unsigned | YES  | MUL | NULL    |                |
| celldb_label_id       | int(11) unsigned | NO   | MUL | NULL    |                |
| information           | text             | YES  |     | NULL    |                |
+-----------------------+------------------+------+-----+---------+----------------+

describe celldb_labels;
+-----------------+------------------+------+-----+---------+----------------+
| Field           | Type             | Null | Key | Default | Extra          |
+-----------------+------------------+------+-----+---------+----------------+
| celldb_label_id | int(11) unsigned | NO   | PRI | NULL    | auto_increment |
| label           | varchar(256)     | YES  |     | NULL    |                |
+-----------------+------------------+------+-----+---------+----------------+
4

3 に答える 3

2

あなたがやろうとしていることは a と呼ばれ、PIVOT残念ながら MySQL には関数がありませんが、ステートメントと集計関数PIVOTを使用して複製できます。CASE

すべてのラベルが事前にわかっていて、その数が管理しやすい場合は、次のようにハードコーディングできます。

SELECT cell_name,
  MAX(CASE WHEN label = 'Cell Type' THEN information END) 'Cell Type',
  MAX(CASE WHEN label = 'DSMZ no.' THEN information END) 'DSMZ no.'
FROM test
GROUP BY cell_name

デモで SQL Fiddle を参照してください

クエリを使用すると、次のようになります。

SELECT cell_name,
  MAX(CASE WHEN label = 'Cell Type' THEN information END) 'Cell Type',
  MAX(CASE WHEN label = 'DSMZ no.' THEN information END) 'DSMZ no.'
from onco_celldb_information as info 
left join onco_celldb_cells as cell 
  on cell.`celldb_cell_id` = info.`celldb_cell_id`
left join onco_celldb_labels as label 
  on info.`celldb_label_id` = label.`celldb_label_id`
GROUP BY cell_name

ただし、不明な数の列があるように見えるため、準備済みステートメントを使用する必要があります。

SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'MAX(case when label = ''',
      label,
      ''' then information end) AS ''',
      label, ''''
    )
  ) INTO @sql
FROM test;


SET @sql = CONCAT('SELECT cell_name, ', @sql, ' FROM test
group by cell_name');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

デモで SQL Fiddle を参照してください

したがって、特定の例では、次のようになります。

SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'MAX(case when label = ''',
      label,
      ''' then information end) AS ''',
      label, ''''
    )
  ) INTO @sql
FROM onco_celldb_labels;

SET @sql = CONCAT('SELECT cell_name, ', @sql, ' 
from onco_celldb_information as info 
left join onco_celldb_cells as cell 
  on cell.`celldb_cell_id` = info.`celldb_cell_id`
left join onco_celldb_labels as label 
  on info.`celldb_label_id` = label.`celldb_label_id`              
group by cell_name');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
于 2012-08-22T10:28:30.797 に答える
1

ラベルの数がわかっている場合は、行がラベルになるようにデータを「ピボット」することができます。

select cell_name,
  max(case when info.celldb_label_id = 1 then information else NULL end) as LabelForInfo1,
  max(case when info.celldb_label_id = 2 then information else NULL end) as LabelForInfo2,
  max(case when info.celldb_label_id = 3 then information else NULL end) as LabelForInfo3,
  ..
from
 onco_celldb_cells as cell
 left join onco_celldb_information as info on cell.celldb_cell_id = info.celldb_cell_id
group by cell.celldb_cell_id, cell.cell_name
order by cell.celldb_cell_id asc;

ラベルの数と名前がわからない場合は、 の情報に基づいて上記のクエリを動的に作成できますonco_celldb_labels。最初に、次のクエリを実行して、上記のクエリの「動的」列を生成します。

select concat(
  'max(case when info.celldb_label_id = ',
   convert(celldb_label_id,char),
   ' then information else NULL end) as `',
   label,
   '`,')
from celldb_labels

返されたすべての行を 1 つの文字列に結合し、メイン クエリから先頭と末尾を追加して実行します。このようにして、動的ラベルが作成されます。私の知る限り、MySQL でテーブルをピボットする唯一の方法です。

于 2012-08-22T10:15:48.953 に答える
0

これはあまりきれいな解決策ではありませんが、列としていくつかのラベルのみが必要で、どれを指定できるかを指定できる場合は、次のように機能するはずです。

SELECT
    s1.cell_name AS cell_name,
    s2.information AS Species,
    s3.information AS Origin
    -- Keep adding selects here for more columns
FROM
    (SELECT distinct cell_name FROM onco_celldb_information) AS s1
    LEFT JOIN onco_celldb_information AS s2
        ON (s1.cell_name = s2.cell_name AND s2.label = 'Species')
    LEFT JOIN onco_celldb_information AS s3
        ON (s1.cell_name = s3.cell_name AND s3.label = 'Origin')
    -- Keep adding more joins here for further columns you want.
于 2012-08-22T10:14:00.560 に答える