Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MS SQL中的交叉表查询/透视表?_Sql_Sql Server 2008_Pivot - Fatal编程技术网

MS SQL中的交叉表查询/透视表?

MS SQL中的交叉表查询/透视表?,sql,sql-server-2008,pivot,Sql,Sql Server 2008,Pivot,我有一个具有以下数据结构的表: terminal | load_time_mns | vehicle _________________________________________ Terminal 1 | 3 | AA Terminal 2 | 10 | AF Terminal 1 | 1 | BF Terminal 6 | 3 | Q

我有一个具有以下数据结构的表:

 terminal    |  load_time_mns  |  vehicle
_________________________________________
 Terminal 1  |   3             |   AA
 Terminal 2  |  10             |   AF
 Terminal 1  |   1             |   BF
 Terminal 6  |   3             |   QRS
 Terminal 6  |   1.4           |   AA
 Terminal 3  |   2.5           |   OP
我试图从每个终端获取加载时间的间隔细分。例如,对于上表,我试图创建如下所示的细分:

terminal     | [0-1 mns]    |  [1-2 mns]    |    [2-3 mns]    |
_______________________________________________________________
Terminal 1   |    0         |     1         |       1    
_______________________________________________________________
Terminal 2   |    0         |     0         |       0     
_______________________________________________________________
Terminal 3   |    0         |     0         |       1
_______________________________________________________________
Terminal 6   |    0         |     1         |       1        

在谷歌搜索了一段时间后,我似乎应该关注pivot函数和交叉表查询。我正在阅读这两个方面的内容,但仍然无法获得类似的帮助:

问题1:

小提琴


请注意,在您的示例中,在[0-1]范围中没有包含1,但在[0-3]范围中包含了3,这似乎不正确。

您可以使用一些动态SQL将其扩展到完整的结果集。创建一个名为Interval的表来存储间隔:

创建表格ex varchar10号航站楼, 加载时间小数10,2, 车辆varchar3 ; 插入ex值 “1号端子”,3号端子,“AA”, “2号航站楼”、10号航站楼、“AF”, “1号端子”,1号,“BF”, “6号端子”,3号端子,“QRS”, “6号端子”,1.4号端子,“AA”, “3号航站楼”,2.5号航站楼,“OP”; 创建表间隔 最小小数10,2, 最大小数10,2, 列名称sysname ; 声明@i int=0
而@i是你的最终格式吗?只有三次间隔?不,我会有1分钟到20分钟的间隔,然后是5分钟的间隔,从20分钟到7小时。谢谢!这正是我需要的。你是对的;我在我的例子中漏掉了。@BadProgrammer:那么你的陈述呢,从1分钟到20分钟,然后从20分钟到7小时,间隔5分钟?您需要多少箱线?
SELECT
  terminal,
  count(CASE WHEN load_time_mns >= 0 AND load_time_mns < 1 THEN 1 END) [0-1 mns],
  count(CASE WHEN load_time_mns >= 1 AND load_time_mns < 2 THEN 1 END) [1-2 mns],
  count(CASE WHEN load_time_mns >= 2 AND load_time_mns < 3 THEN 1 END) [2-3 mns]
FROM t
GROUP BY terminal
|   TERMINAL | 0-1 MNS | 1-2 MNS | 2-3 MNS |
|------------|---------|---------|---------|
| Terminal 1 |       0 |       1 |       0 |
| Terminal 2 |       0 |       0 |       0 |
| Terminal 3 |       0 |       0 |       1 |
| Terminal 6 |       0 |       1 |       0 |
DECLARE @t TABLE ( terminal VARCHAR(10), load_time_mns DECIMAL(5,2), vehicle VARCHAR(3))

INSERT INTO @t ( terminal, load_time_mns, vehicle )
VALUES 
('Terminal 1'  ,   3             ,   'AA'),
('Terminal 2'  ,  10             ,   'AF'),
('Terminal 2'  ,  20             ,   'AF'),
('Terminal 1'  ,   1             ,   'BF'),
('Terminal 1'  ,   25             ,   'BF'),
('Terminal 6'  ,   3             ,   'QRS'),
('Terminal 6'  ,   1.4           ,   'AA'),
('Terminal 3'  ,   2.5           ,   'OP')

;WITH intervals AS
(
    SELECT m = 0, n = 1 
    UNION ALL
    SELECT CASE WHEN m < 20 THEN m+1 ELSE m+5 END, CASE WHEN n < 20 THEN n+1 ELSE n+5 END
    FROM intervals
    WHERE n<420
)
SELECT terminal, load_time_mns, vehicle, 
    interval = CAST(m AS VARCHAR(10)) + '-' + CAST(n AS VARCHAR(10)), m
INTO ##tmp
FROM intervals i
LEFT JOIN @t t 
  ON t.load_time_mns >= i.m 
 AND t.load_time_mns < i.n 
OPTION (MAXRECURSION 0)


DECLARE @cols VARCHAR(MAX) = 
    STUFF(CAST((SELECT ',' + QUOTENAME(interval)
           FROM (
            SELECT DISTINCT interval, m
            FROM ##tmp
           ) t
           ORDER BY m
           FOR XML PATH(''), TYPE
          ) AS VARCHAR(MAX)),1,1,'')

DECLARE @sql VARCHAR(MAX) = '
    SELECT terminal, ' + @cols + '
    FROM (
        SELECT terminal, vehicle, interval
        FROM ##tmp
    ) t
    PIVOT (
        COUNT(vehicle)
        FOR interval IN (' + @cols + ')
    ) p
'

EXEC(@sql)

DROP TABLE ##tmp