Sql 将表的多个列分组以获得如图所示的输出的有效方法是什么?
我有一个表,用来跟踪我访问某个目录中的文件的次数。以下是一个示例Sql 将表的多个列分组以获得如图所示的输出的有效方法是什么?,sql,sql-server,Sql,Sql Server,我有一个表,用来跟踪我访问某个目录中的文件的次数。以下是一个示例 DirectoryName FileName A Ab.pdf B bc.pdf C cd.pdf A de.pdf A kl.mp3 B pq.pdf B pq.pdf B pq.pd
DirectoryName FileName
A Ab.pdf
B bc.pdf
C cd.pdf
A de.pdf
A kl.mp3
B pq.pdf
B pq.pdf
B pq.pdf
每次访问文件时,都会添加其目录和名称
另外,请注意,一个文件不能出现在多个目录中
请单击以获取此表所基于的表格示例
我希望输出像这样发生
Directory DirectoryCount FileName FileCount
A 3 Ab.pdf 1
de.pdf 1
kl.pdf 1
B 4 bc.pdf 1
pq.pdf 3
C 1 cd.pdf 1
这里DirectoryCount
是指目录被访问的次数,FileCount
是指文件被访问的次数
请单击此处查看我希望模拟的输出示例,尽管我希望每个文件只显示一次。请尝试以下操作
SELECT CASE
WHEN directoryCountFinder.DirectoryName = LAG( directoryCountFinder.DirectoryName ) OVER ( ORDER BY directoryCountFinder.DirectoryName ) THEN
''
ELSE
directoryCountFinder.DirectoryName
END AS DirectoryName,
CASE
WHEN directoryCountFinder.DirectoryName = LAG( directoryCountFinder.DirectoryName ) OVER ( ORDER BY directoryCountFinder.DirectoryName ) THEN
''
ELSE
CONVERT( VARCHAR( 10 ),
DirectoryCount )
END AS DirectoryCount,
FileName,
FileCount
FROM ( SELECT DirectoryName AS DirectoryName,
COUNT( DirectoryName ) AS DirectoryCount
FROM tblTable
GROUP BY DirectoryName
) directoryCountFinder
JOIN ( SELECT DirectoryName AS DirectoryName,
FileName AS FileName,
COUNT( FileName ) AS FileCount
FROM tblTable
GROUP BY DirectoryName,
FileName
) fileCountFinder ON directoryCountFinder.DirectoryName = fileCountFinder.DirectoryName;
当我针对使用提供的示例数据创建的测试数据库测试语句时,输出按指定进行
我用来形成我的语句的逻辑是,我们需要一个计数,在提供的列表中,每个目录发生了多少次,每个文件发生了多少次
为了计算每个目录出现的次数,我使用了以下查询
SELECT DirectoryName AS DirectoryName,
COUNT( DirectoryName ) AS DirectoryCount
FROM tblTable
GROUP BY DirectoryName
我使用了一个类似的查询来计算每个文件出现的次数
SELECT DirectoryName AS DirectoryName,
FileName AS FileName,
COUNT( FileName ) AS FileCount
FROM tblTable
GROUP BY DirectoryName,
FileName
DirectoryName
包含在这里,因为我需要它将此子查询的结果与另一个子查询的结果连接起来
一旦两个子查询连接起来,我们就有了一个看起来像所需输出的数据集,FileName
和FileCount
的每个值都是重复的。因此,我应用CASE
语句,测试当前记录中DirectoryName
的值是否与前一个记录中的值相同,如果相同,则输出空字符串('
),而不是字段值
由于DirectoryCount
是一个数字,因此如果只列出DirectoryCount
的值,则输出中该字段中的所有值也将是数字,包括空字符串'
,它将显示为0
。但如果我们将DirectoryCount
格式化为输出字符串,则空字符串将显示为空字符串,即空值,因此使用CONVERT(VARCHAR(10),DirectoryCount)
如果您有任何问题或意见,请随时发表相应的意见。试试以下方法:
DECLARE @table TABLE (DirectoryName NVARCHAR(1),FileNames NVARCHAR(10))
INSERT INTO @table VALUES
('A','Ab.pdf'),('B','bc.pdf'),('C','cd.pdf'),('A','de.pdf'),('A','kl.mp3')
SELECT * FROM @table -- your table
;WITH A AS (
SELECT DirectoryName, COUNT(DirectoryName) DirectoryCount FROM @table
GROUP BY DirectoryName )
SELECT CASE WHEN rowid = 1 THEN A.DirectoryName ELSE '' END DirectoryName,
CASE WHEN rowid = 1 THEN CONVERT(VARCHAR,A.DirectoryCount) ELSE '' END DirectoryCount,
B.FileNames,C.Filecount
FROM A LEFT JOIN (
SELECT ROW_NUMBER() OVER (PARTITION BY DirectoryName ORDER BY DirectoryName)
rowid, DirectoryName, FileNames FROM @table
) B ON A.DirectoryName = B.DirectoryName LEFT JOIN
(SELECT DirectoryName,FileNames,COUNT(FileNames) Filecount FROM @table GROUP BY FileNames,DirectoryName)
C ON C.FileNames = B.FileNames AND B.DirectoryName = C.DirectoryName --your output
我无法让我的本地或SQLfiddle服务器工作以进行检查,但您需要类似以下内容:
select
DirectoryName,
count(*) over( partition by directoryName) as DirectoryCount,
FileName,
count(*) over (partition by directoryname,filename) as filenameCount
from tblTable
order by DirectoryName,filename
要获取间距,请使用前端检测DirectoryName中的更改。如果需要,您还可以选择行号(按目录名分区)
并仅显示1
s
还有此选项(同样,用于删除复制的前端)
这对我来说毫无意义。那么什么是更好的方法呢?1)目录
F
的行在哪里。是最后一排吗?那么为什么不把directoryname和count放在那一行呢2)为什么你的第四行de.pdf
的目录名为空。根据这个逻辑,输出中kl.pdf
在哪里?在输出中de.pdf
和kl.mp3
应该显示在ab.pdf
下,并且显示DirectoryName
F
的行?我已经编辑了这个问题。实际上,我想要目录名和计数,文件名和计数在同一行。目录或文件之间没有关系。ORDER BY子句在视图、内联函数、派生表、子查询和公共表表达式中无效,除非还指定了TOP、OFFSET或FOR XML。Msg 156,第15级,状态1,第15行关键字“订单”附近的语法不正确。代码中添加了缺少的行。请在我研究您的邮件时尝试新答案。答案已更新。请注意,我仍在设置SQL-SERVER的第一个副本,因此可能需要一段时间才能测试我的代码。如果您要包含一个脚本来生成和填充示例表,这将有助于提高问题的质量。不客气。如果您认为这是提供的最合适的答案,并且它确实回答了您的问题,那么请通过单击答案顶部旁边的勾号来接受它。您好,我已经修改了问题。希望你能帮我得到输出。谢谢文件名是多余的。我上传了一个快照。请看一看。谢谢你的表格还是我查询后的输出?这是你查询后的输出。你期望的输出是什么,你能告诉我吗?
select d.DirectoryName, d.DirectoryCount , f.Filename,f.FileNameCount from
(
select DirectoryName,
count(*)as DirectoryCount
from tblTable
group by DirectoryName
) as d
inner join
(
select DirectoryName, FileName,
count(*)as filenameCount
from tblTable
group by DirectoryName,FileName
) as f
on d.directoryName=f.DirectoryName
order by DirectoryName, FileName