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