1

「通常の」クエリでは、次のように表示されるデータがあります。

Val1    Val2
----    ----
1   2
2   [blank]
3   2
4
5   1
6   3
..
96  1

ただし、私が欲しいのは次のようなものです(行数を12に制限する必要があります):

Val1    Val2    Val1    Val2    Val1    Val2    ... Val1    Val2
----    ----    ----    ----    ----    ----
1   2   13  1   25  [blank]  ...    85  1
2   [blank] 14  1   26  3   ... 86  [blank]
..  ... ... ... ... ... ... ... ...
12  1   24  [blank] 36  2   ... 96  3

私にそれを与えるselectステートメントはありますか?私は SQL の専門家ではありませんが、次のようなことを (意味的に) 考えています。

select (select val1, val2 from dbtable where val1 < 13),
(select val1, val2 from dbtable where val1 > 12 and val1 < 25),
...
(select val1, val2 from dbtable where val1 > 84)
from dbtable

アップデート

dfb の sql の例への応答:

私がこれを行うとき:

SELECT t1.Val1, t1.Val2 FROM 
(SELECT Val1, Val2, rownum() as rownum FROM dbTable) t1 
INNER JOIN (SELECT Val1, Val2, rownum() as rownum FROM dbTable) t2 
ON t1.rownum/2 == t2.rownum/2

... 「期待される場所に FROM キーワードが見つかりません」というメッセージが表示されます

そして、これを行うと(「rownum()」のものを削除します):

SELECT t1.Val1, t1.Val2 FROM 
(SELECT Val1, Val2 FROM dbTable) t1 
INNER JOIN (SELECT Val1, Val2 FROM dbTable) t2 
ON t1.rownum/2 == t2.rownum/2

... 「ORA-01747: 無効な user.table.column、table.column、または列の指定」が表示されます

更新 2

Sully の例が最も近いものでしたが、UNION SQL が機能することを願っています。有効な値を押し下げずに実行できればもっとよいでしょう。現状では、適切なレイアウトがありますが、その 16X12 レイアウト内で必要な場所に val が表示されません。とにかく、後世のために、行と列が動的に作成される方法を次に示します (以下のコードに示されているものとは異なり、互いに同一ではありません)。

//prebuild 12 rows in outputDt 
int iRows = 12;
while (iRows > 0)
{
    DataRow row = outputDt.NewRow();
    outputDt.Rows.Add(row);
    iRows -= 1;
}

//prebuild 16 cols in outputDt 
int iCols = 16;
while (iCols > 0) {
    DataColumn col = new DataColumn();
    outputDt.Columns.Add(col);
    iCols -= 1;
}

最終更新

動作しました。DataGridView に交互の垂直列を設定することは可能ですか? を参照してください。

4

3 に答える 3

2

このようなことができますが、きれいではありません。プレゼンテーション層でこれを行うことについてのコメントは適切です。

SELECT ... FROM
(SELECT v1,v2,rownum as rn FROM Foo WHERE mod(rownum,2)=1) t1
INNER JOIN (SELECT v1,v2,rownum as rn FROM Foo WHERE mod(rownum,2)=0) t2
ON (t1.rn/2 = t2.rn/2)
于 2012-08-22T17:57:20.600 に答える
2

行が常に 96 になることがわかっている場合、これは静的なピボット手法の 1 つです。

select val1 AS col1, val2 AS col2,NULL AS Col3,NULL AS Col4 ,NULL AS Col5,NULL AS Col6,NULL AS col7,NULL AS Col8 from dbtable where val1 < 13
UNION 
select NULL AS col1,NULL AS col2 ,val1 AS Col3, val2 AS Col4,NULL AS Col5,NULL AS Col6,NULL AS col7,NULL AS Col8 from dbtable where val1 > 12 and val1 < 25
UNION
select NULL AS col1,NULL AS col2 ,NULL AS Col3, NULL AS Col4,val1 AS Col5,val2 AS Col6,NULL AS col7,NULL AS Col8 from dbtable where val1 > 25 and val1 < 37
.....
...AND So ON

行数が不明な場合は、動的ピボットを実行する必要があります。

注: 上記の構文は SQL Server 2008 用です。Oracle でも変わらないことを願っています。

于 2012-08-22T18:26:57.513 に答える
2

これのボーナスは、より多くのデータが得られた場合、必要に応じて水平方向の列を作成するだけで、12 行のデータを超えることはありません。「in-SQL」の方法では、より多くのデータを表示する必要がある場合は、コードを変更する必要があります。

免責事項:これは完全にすぐに使えるものです(C#は私が慣れているものです)。これを行うには、おそらくもっと良い方法があります (Linq?) ロジックはかなり近いはずですが、これにより、この非常に限定された表示以外の目的でデータのリストを使用する柔軟性が得られます。

DataTable dt = ResultsFromSproc();
DataTable outputDt = new DataTable();

//prebuild 12 rows in outputDt
int iRows = 12;
while(iRows > 0) {
    outputDt.Rows.Add(new DataRow());
    iRows-=1;
}

int outputColumn = 0;
for(int i = 0; i < dt.Rows.Count; i+=1){
    DataRow dr = dt.Rows[i];

    if(i % 12 == 0 && i > 0) { 
        //add two more columns to outputDt
        outputDt.Columns.Add() //Not sure but you might need to give it a name. (outputColumn+2).ToString() should work
        outputDt.Columns.Add() //Not sure but you might need to give it a name. (outputColumn+3).ToString() should work
        outputColumn += 1;
    }
    outputDt.Rows[i%12][outputColumn] = dr[0];
    outputDt.Rows[i%12][outputColumn + 1] = dr[1];
}
//Step2: Bind to outputDt. Step 3: Profit!

ALTERNATE バージョン: val1 == 48 がセル 48 に入るという要件について (コメントを参照)

DataTable dt = ResultsFromSproc();
DataTable outputDt = new DataTable();

//prebuild 12 rows in outputDt
int iRows = 12;
while(iRows > 0) {
    outputDt.Rows.Add(new DataRow());
    iRows-=1;
}

int outputColumn = 0;
int iMaxCell = (int)dt.Select("MAX(Val1)")[0][0];
//ASSUMING YOU HAVE ALREADY DONE AN ORDER BY Val1 in SQL (if not you need to sort it here first)
for(int i = 0; i < iMaxCell; i+=1){
    DataRow dr = dt.Rows[i];

    if(i % 12 == 0 && i > 0) { 
        //add two more columns to outputDt
        outputDt.Columns.Add() //Not sure but you might need to give it a name. (outputColumn+2).ToString() should work
        outputDt.Columns.Add() //Not sure but you might need to give it a name. (outputColumn+3).ToString() should work
        outputColumn += 2;
    }
    //compare to i+1 if your data starts at 1
    if((int)dr[0] == (i+1)){
        outputDt.Rows[i%12][outputColumn] = dr[0];
        outputDt.Rows[i%12][outputColumn + 1] = dr[1];
    }
}
//Step2: Bind to outputDt. Step 3: Profit!
于 2012-08-22T18:27:17.403 に答える