仅返回包含6个实例的记录,其中每列中的所有值都相同

时间:2014-12-10 14:52:08

标签: sql sql-server

我正在构建一个查询并陷入困境,我不确定我想要达到的目标是否可能。

我构建了一个返回如下结果的查询:

enter image description here

使用以下查询:

declare @stDate     varchar(10) = '1988-01-01';
declare @fromDate   varchar(10) = '2014-06-01';
declare @toDate     varchar(10) = '2014-11-30';

select  PART.PARTNAME                                                       as 'PART NUMBER'
    ,   PART.PARTDES                                                        as 'DESCRIPTION'
    ,   ( CONVERT(date, DATEADD(day, WARHSCOST.CURDATE/1440, @stDate)))     as 'DATE'
    ,   ( CONVERT(float, WARHSCOST.BALANCE ) / 1000 )                       as 'BALANCE' 
    ,   ( CONVERT(decimal(19,2), WARHSCOST.COST) )                          as 'VALUE'

from    WARHSCOST  
    inner join PART         on ( PART.PART = WARHSCOST.PART ) 
    inner join WAREHOUSES   on ( WAREHOUSES.WARHS = WARHSCOST.WARHS ) 

where   ( CONVERT(date, DATEADD(day, WARHSCOST.CURDATE/1440, @stDate)) between @fromDate and @toDate ) 
    and ( WAREHOUSES.WARHSNAME = 'Fin' )
    and ( PART.PARTNAME NOT LIKE 'ZZ%' )
    and ( WARHSCOST.COST > 0 )

group by PART.PARTNAME
    ,    PART.PARTDES
    ,    WARHSCOST.CURDATE
    ,    WARHSCOST.BALANCE
    ,    WARHSCOST.COST
    having count(*) > 0 

order by 1 , 4

但我希望将结果仅限于那些

enter image description here

我需要再添加一个过滤器/标准,但我完全不知道如何去做它:

  • 仅显示所有6个月内相同余额的部分(,如第二个屏幕截图所示

任何帮助都非常受欢迎,因为它可以节省我很多时间来迭代当前的记录集,只是为了消除所有6个月没有相同余额的记录。

如果我需要更多信息,请告诉我,我会尽力更新问题。

2 个答案:

答案 0 :(得分:1)

如何添加

having count(distinct CONVERT(date, DATEADD(day, WARHSCOST.CURDATE/1440, @stDate))) = 6
and count(distinct WARHSCOST.BALANCE) = 1

答案 1 :(得分:1)

一种方法:将您拉入的数据加载到临时表中,然后从临时表中分析并提取符合条件的内容。在SQL 2005及更高版本中,您可以使用CTE(公用表表达式)完成所有这些操作。没有基础表我无法检查语法,但这里的概念是可靠的。

您的原始查询在下面的第一个cte中完全不受影响。我添加了一些--comments,只是因为。

declare @stDate     varchar(10) = '1988-01-01';
declare @fromDate   varchar(10) = '2014-06-01';
declare @toDate     varchar(10) = '2014-11-30';


WITH cteBase (PartName, PartDes, PartDate, PartBal, PartCost)
 as (

--  CTE pulls out the "basic" data
select  PART.PARTNAME                                                     --  as 'PART NUMBER'
    ,   PART.PARTDES                                                      --  as 'DESCRIPTION'
    ,   ( CONVERT(date, DATEADD(day, WARHSCOST.CURDATE/1440, @stDate)))   --  as 'DATE'
    ,   ( CONVERT(float, WARHSCOST.BALANCE ) / 1000 )                     --  as 'BALANCE' 
    ,   ( CONVERT(decimal(19,2), WARHSCOST.COST) )                        --  as 'VALUE'

from    WARHSCOST  
    inner join PART         on ( PART.PART = WARHSCOST.PART ) 
    inner join WAREHOUSES   on ( WAREHOUSES.WARHS = WARHSCOST.WARHS ) 

where   ( CONVERT(date, DATEADD(day, WARHSCOST.CURDATE/1440, @stDate)) between @fromDate and @toDate ) 
    and ( WAREHOUSES.WARHSNAME = 'Fin' )
    and ( PART.PARTNAME NOT LIKE 'ZZ%' )
    and ( WARHSCOST.COST > 0 )

group by PART.PARTNAME
    ,    PART.PARTDES
    ,    WARHSCOST.CURDATE
    ,    WARHSCOST.BALANCE
    ,    WARHSCOST.COST
--    having count(*) > 0 --  This doesn't do anything, if count(*) were 0 there would be no row

--order by 1 , 4
    )
 , cteSix (PartName, PartBal)
   as (

--  cte that identifies what from the first cte qualifies
select PartName, PartBal
 from cteBase
 group by PartName, PartBal
 having count(*) = 6

    )

SELECT
   ba.PartName  as  [PART NUMBER]  --  Embedded space
  ,ba.PartDes   as  DESCRIPTION
  ,ba.PartDate  as  [DATE]         --  Reserved word
  ,ba.PartBal   as  BALANCE
  ,ba.PartCost  as  VALUE
 from cteBase ba
  inner join cteSix six
   on six.PartName = ba.PartName
 order by ba.PartName, ba.PartBal

此外,如果WARHSCOST.CURDATE是日期数据类型(而不是字符串或整数),则您不应该将其转换为日期。