T-SQL查询自由位置的矩阵表

时间:2012-11-13 09:43:48

标签: sql sql-server sql-server-2008 tsql

我正在尝试为矩阵表构建一个具有如下模式的查询:

X   | Y   | Z   | Disabled   | OccupiedId |
--------------------------------------------
1     1     1       0            NULL
1     2     1       0            NULL
1     3     1       1            NULL
1     4     1       0               1
1     5     1       0               2
1     6     1       0               3
1     7     1       0               4
1     1     2       0            NULL
1     2     2       0            NULL
1     3     2       0            NULL
1     4     2       0            NULL
1     5     2       0            NULL
1     6     2       0            NULL
1     7     2       0            NULL

我想为X,Z分组并找到Y上的第一个可用位置。 无论如何都可以使用,禁用且不占用。

在提供的示例中,此查询应返回:

X   | Z   | FreeY
--------------------------------------------
 1     1     2
 1     2     7

考虑到从末尾开始填充每个(X,Z)(MAX Y是常数),查询应选择第一个空闲Y(或最后一个占用Y)

我尝试过不同的方法但没有成功:( 任何建议都非常感谢! 亲切的问候, d。

2 个答案:

答案 0 :(得分:3)

SQL fiddle

 CREATE TABLE Coordinate
(  X int, Y int,Z int, Disabled bit, OccupiedId int)

INSERT INTO Coordinate VALUES (1,1,1, 1, NULL)
INSERT INTO Coordinate VALUES (1,1,2, 0, NULL)
INSERT INTO Coordinate VALUES (1,1,3, 0, NULL)
INSERT INTO Coordinate VALUES (1,1,4, 0, NULL)
INSERT INTO Coordinate VALUES (1,2,1, 0, NULL)
INSERT INTO Coordinate VALUES (1,2,2, 0, NULL)
INSERT INTO Coordinate VALUES (1,2,3, 0, 123)
INSERT INTO Coordinate VALUES (1,2,4, 0, NULL)
INSERT INTO Coordinate VALUES (1,2,5, 1, NULL)

SELECT X, Z, MIN(Y) AS FirstFreePosition
FROM Coordinate
WHERE Disabled = 0 AND OccupiedId IS NULL
GROUP BY X, Z

OR -- if you need the unavailable combinations too, then something like this:

SELECT X, Z, MIN(CASE 
                 WHEN Disabled = 1 OR OccupiedId IS NOT NULL 
                 THEN 1000 --a big number
                 ELSE Y END) AS FirstFreePosition
FROM Coordinate
GROUP BY X, Z

答案 1 :(得分:2)

对于您的编辑(禁用=位列),此查询显示lastOccupiedID以及firstFreeY

  select x, z,
         max(case when disabled=1 or occupiedid is not null
             then Y else 0 end) lastOccupiedPosition,
         maX(case when disabled=0 AND occupiedid is null
             then Y else 0 end) firstFreeY
    from matrix
group by x, z
order by x, z;

<小时/> SQL Fiddle

MS SQL Server 2008架构设置

create table matrix(
X int  , Y int  , Z int  , Disabled varchar(5)  , OccupiedId int );
insert matrix values
(1    , 1   , 1   , 'True'       , NULL      ),
(1    , 1   , 2   , 'False'      , NULL      ),
(1    , 1   , 3   , 'False'      , NULL      ),
(1    , 1   , 4   , 'False'      , NULL      ),
(1    , 2   , 1   , 'False'      , NULL      ),
(1    , 2   , 2   , 'False'      , NULL      ),
(1    , 2   , 3   , 'False'      , 123       ),
(1    , 2   , 4   , 'False'      , NULL      );

查询1

  select x, z,
         max(case when disabled='true' or occupiedid is not null
             then Y else 0 end) lastOccupiedPosition
    from matrix
group by x, z
order by x, z

<强> Results

| X | Z | LASTOCCUPIEDPOSITION |
--------------------------------
| 1 | 1 |                    1 |
| 1 | 2 |                    0 |
| 1 | 3 |                    2 |
| 1 | 4 |                    0 |