3

N 次元空間のセルは、以下の 2 つのテーブルでモデル化されます。単一のセル (CellID による) を取得し、各軸に沿って指定されたセル (それ自体を含む) と "インライン" である他のすべてのセルを返すスクリプトが必要です。

たとえば、空間に 3 つの次元 (X、Y、Z) があり、X に 2 つの位置、Y に 2、Z に 3 があるとします。座標 {1,1,1} のセルが与えられた場合、結果は次のようになります。

+----------+---------+
| AxisCode |  Cell   |
+----------+---------+
| X        | {1,1,1} |   <- showing coordinates for clarity, but should be CellID
| X        | {2,1,1} |
| Y        | {1,1,1} |
| Y        | {1,2,1} |
| Z        | {1,1,1} |
| Z        | {1,1,2} |
| Z        | {1,1,3} |
+----------+---------+

私はこれに何時間も費やしましたが、特定の数のディメンションに対してハードコードされたクエリしか思いつきません....

注意: 3 つのテーブルのスキーマを変更することはできません。スクリプトは N 次元で機能する必要があり、ループやカーソルを使用しないでください。

互換性は MS SQL 2008 R2 でなければなりません

どんなアイデアもありがたく受け取った!

create table dbo.Cells(
    CellID int not null,
    CellValue int not null,
    constraint PK_Cells primary key (CellID)
    )

create table dbo.AxisPositions(
    AxisCode char(1) not null,      -- X, Y, Z etc
    PositionOnAxis int not null,    -- 1, 2, 3, 4 etc
    constraint PK_AxisPositions primary key (AxisCode, PositionOnAxis)
    )

create table dbo.CellAxes(
    CellID int not null,
    AxisCode char(1) not null,      -- X, Y, Z etc
    PositionOnAxis int not null,    -- 1, 2, 3, 4 etc
    constraint PK_CellAxes primary key (CellID, AxisCode),
    constraint FK_CellAxes_Cells foreign key (CellID) references Cells(CellID),
    constraint FK_CellAxes_AxisPositions foreign key (AxisCode, PositionOnAxis) references AxisPositions(AxisCode, PositionOnAxis)
    )

-- Example data

insert Cells (CellID, CellValue)
values (1, 67), (2, 45), (3, 0), (4, 4), (5, 78), (6, 213), (7, 546), (8, 455), (9, 12), (10, 67), (11, 4), (12, 5)

insert AxisPositions (AxisCode, PositionOnAxis)
values ('X', 1), ('X', 2), ('Y', 1), ('Y', 2), ('Z', 1), ('Z', 2), ('Z', 3)

insert CellAxes (CellID, AxisCode, PositionOnAxis)
values  (1, 'X', 1), (1, 'Y', 1), (1, 'Z', 1),
        (2, 'X', 2), (2, 'Y', 1), (2, 'Z', 1),
        (3, 'X', 1), (3, 'Y', 2), (3, 'Z', 1),
        (4, 'X', 2), (4, 'Y', 2), (4, 'Z', 1),
        (5, 'X', 1), (5, 'Y', 1), (5, 'Z', 2),
        (6, 'X', 2), (6, 'Y', 1), (6, 'Z', 2),
        (7, 'X', 1), (7, 'Y', 2), (7, 'Z', 2),
        (8, 'X', 2), (8, 'Y', 2), (8, 'Z', 2),
        (9, 'X', 1), (9, 'Y', 1), (9, 'Z', 3),
        (10, 'X', 2), (10, 'Y', 1), (10, 'Z', 3),
        (11, 'X', 1), (11, 'Y', 2), (11, 'Z', 3),
        (12, 'X', 2), (12, 'Y', 2), (12, 'Z', 3)
4

4 に答える 4

3

質問の元の2つのテーブルに基づいて、動的SQLを記述して列を作成し、それを使用して「インライン」を定義するために使用しているものと比較できます。

-- Build list of column values to pivot
DECLARE @cols NVARCHAR(1000);
SELECT @cols =
STUFF((SELECT N'],[' + axiscode
       FROM (SELECT DISTINCT axiscode FROM CellAxes) AS O(axiscode)
       ORDER BY axiscode
       FOR XML PATH('')
      ), 1, 2, '') + N']';

SELECT @cols;

-- Build dynamic SQL query for pivoting   
DECLARE @sql NVARCHAR(2000);
SET @sql =
N'WITH pivotedData AS (SELECT CellID, ' + @cols +
N'FROM CellAxes ' +
N'PIVOT ' +
N'(MAX(PositionOnAxis) FOR AxisCode IN (' + @cols + N')) AS P)' + 
N'SELECT * from pivotedData'
-- Modify this query with a generated WHERE clause that defines what "inline" means.
;

EXEC(@sql);

@BillKarwin が正しいことに注意してください。スキーマを data に保存しているため、ストレート SQL でこれを行う安全な推奨方法はありません。

于 2013-11-14T17:01:53.893 に答える