在SQL中仅显示所需的结果

时间:2013-12-17 23:05:20

标签: sql

我需要一些帮助才能完成此查询。以下是我到目前为止的情况:

select
    (select count(fileName)
    from PDFFile
    where dateTime > cast(getdate() as date)
    and stateId = 17) AS "Files on SFTP"
    ,
    (select count(fileName)
    from PDFFile
    where dateTime > cast(getdate() as date)
    and stateId = 12) AS "Files Pass"
    ,
    ((select count(fileName)
    from PDFFile
    where dateTime > cast(getdate() as date)
    and stateId = 17)
    -
    (select count(fileName)
    from PDFFile
    where dateTime > cast(getdate() as date)
    and stateId = 12)) AS "Diff"

这将给我3列结果。第一个结果将是一个数字,第二个将是一个数字,第三个将是差异。甚至可能有更好的方法来写这个,但我仍然是一个新手。提示:每个州的数据库中都有一个条目:

fileName  |dateTime                 | stateID
--------+---------+-----------------+---------
 abc.pdf  | 2013-12-17 12:03:14.597 | 17
 abc.pdf  | 2013-12-17 12:06:23.096 | 12
 xyz.pdf  | 2013-12-17 12:09:16.583 | 17
 xyz.pdf  | 2013-12-17 12:10:19.823 | 12

无论如何最终结束......

我需要有第4列或单独的查询(可能是UNION?),它根据diff中的结果提取fileNames。

假设diff是40,第4列或单独的查询应列出40个名称。有时差异可能是负的,所以假设它的-40应该列出40个名字。

非常感谢协助。谢谢!

2 个答案:

答案 0 :(得分:1)

您可以使用条件聚合大大简化查询:

select sum(case when dateTime > cast(getdate() as date) and stateId = 17 then 1 else 0
           end) as "Files on SFTP",
       sum(case when  dateTime > cast(getdate() as date) and stateId = 12 then 1 else 0
           end) AS "Files Pass",
       (sum(case when dateTime > cast(getdate() as date) and stateId = 17 then 1 else 0
            end) -
        sum(case when  dateTime > cast(getdate() as date) and stateId = 12 then 1 else 0
            end)
       ) as diff
from PDFFile;

要获取第一组中的文件列表而不是第二组中的文件列表需要更多逻辑。问题是聚合单位是文件级别。

select PDFFile
from PDFFile
group by PDFFile
having sum(case when dateTime > cast(getdate() as date) and stateId = 17 then 1 else 0
           end) > 0 and
       sum(case when dateTime > cast(getdate() as date) and stateId = 12 then 1 else 0
           end) = 0;

having子句的每个部分计算与两个条件匹配的行数(对于每个文件)。您希望至少有一行与第一个条件匹配(因此> 0),并且没有与第二个条件匹配的行(= 0)。

答案 1 :(得分:1)

这种类型的“将行数据组合成一列”问题在Stack Overflow上出现了很多问题,尽管它有其位置,但以另一种方式解决问题通常更容易,更有效。

例如,要求SQL“为我提供stateid = 17的所有文件名”要容易得多,将它们返回到您的应用程序然后让应用程序显示它们。也可能是您的用户不希望看到它们,直到他们感兴趣的特定摘要行需要深入研究。以电子邮件为例 - 您可能只需要查看30个字符的主题行,并且知道您不需要下载1Mb电子邮件正文。

对于您的第一个问题,尽管编写查询的方式更简单(也更有效)。请注意,此示例未经测试

select 
   sum(case when stateId = 17 then 1 else 0 end) as "Files on SFTP",
   sum(case when stateId = 12 then 1 else 0 end) as "Files Pass",
   sum(case when stateId = 17 then 1 else 0 end) - 
          sum(case when stateId = 12 then 1 else 0 end) as "Diff",
from 
   PdfFile 
where 
   datetime > getdate()  

我在这里使用CASE来防止必须执行三个单独的子查询。子查询效率低下。 CASE并不好,但它比子查询更快。我还将您的日期时间检查放在查询的底部,作为每个检查通用的WHERE。