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