对表的多个列进行分组以获得输出的有效方法是什么?

时间:2017-04-14 02:46:37

标签: 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.pdf

每次访问文件时,都会添加目录和名称。

另请注意,文件可能不会出现在多个目录中。

请点击here以获取相关表格的示例。

我希望输出像这样......

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是访问该文件的次数。

请点击here获取我希望模仿的输出示例,但我希望每个文件只出现一次。

3 个答案:

答案 0 :(得分:0)

请尝试以下方法......

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包含在这里,因为我需要它将此子查询的结果加入到另一个子结果的结果中。

两个子查询连接后,我们有一个看起来像所需输出的数据集,但重复FileNameFileCount的每个值除外。因此,我应用CASE语句进行测试,以查看DirectoryName的值是否与当前记录中的值相同,如果是,则输出空字符串{{1而不是字段值。

由于''是一个数字,如果您只是列出DirectoryCount的值,包括空字符串DirectoryCount,那么输出中该字段中的所有值也将是数字显示为''。但是如果我们将0格式化为输出的字符串,那么空字符串将显示为空字符串,即空值,因此使用DirectoryCount

如果您有任何问题或意见,请随时发表评论。

答案 1 :(得分:0)

试试这个:

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

答案 2 :(得分:0)

我无法让我的本地或SQLfiddle服务器进行检查,但您需要这样的内容:

mysqli_query($conn, "UPDATE member_db SET 'Fine_Amt'=('Fine_Amt' + 100) WHERE 'Member_id' = '$mem_id'");

要获取间距,请使用前端检测DirectoryName中的更改。如果您还想要,也可以选择 select DirectoryName, count(*) over( partition by directoryName) as DirectoryCount, FileName, count(*) over (partition by directoryname,filename) as filenameCount from tblTable order by DirectoryName,filename 并仅显示ROW_NUMBER OVER (partition by DirectoryName) s

此选项(同样,前端用于删除欺骗)

1