T-SQL返回不存在的记录

时间:2014-03-25 00:16:44

标签: sql-server tsql

我对SQL非常陌生,我需要一种方法来返回 NULL 或0,对于每个外科医生来说,没有记录存在的年和季度。只有2个产品系列应该返回(膝盖和肩膀),如果外科医生曾经使用该系列产品,我只需要缺少年份/季度。例如,如果史密斯,约翰只有膝盖,那么我不需要为肩膀做空。

这是我到目前为止的查询,但我还没有弄清楚如何包含没有价值的年份和季度。

SELECT  q.Surgeon_Name ,
        q.Product_Family ,
        First_Date ,
        q.Year ,
        q.Quarter ,
        CAST(ROUND(q.Monthly_Average, 2) AS MONEY) AS 'Monthly Average'
FROM    ( SELECT DISTINCT
                    RTRIM(confirmed_to) AS 'Surgeon_Name' ,
                    Product_Family ,
                    YEAR(rev_ship_date) AS 'Year' ,
                    DATENAME(Quarter, CAST(REV_SHIP_DATE AS DATETIME)) AS 'Quarter' ,
                    ( SUM(amount) / 3 ) AS 'Monthly_Average'
          FROM      Vsoicl
                    LEFT JOIN Product_Line_Desc ON vsoicl.PART_ID = Product_Line_Desc.Part_ID
          WHERE     vsoicl.PRODUCT_LINE <> 'MIRR'
                    AND Product_Family IS NOT NULL
                    AND Product_Family <> 'NULL'
                    AND CONFIRMED_TO <> ''
                    AND REV_SHIP_DATE >= '2013-01-01'
          GROUP BY  CONFIRMED_TO ,
                    Product_Family ,
                    YEAR(rev_ship_date) ,
                    DATENAME(Quarter, CAST(REV_SHIP_DATE AS DATETIME))
        ) AS q
        LEFT JOIN ( SELECT DISTINCT
                            RTRIM(confirmed_to) AS 'Surgeon_Name' ,
                            Product_Family ,
                            CAST(MIN(rev_ship_date) AS DATE) AS 'First_Date'
                    FROM    Vsoicl
                            LEFT JOIN Product_Line_Desc ON vsoicl.PART_ID = Product_Line_Desc.Part_ID
                    WHERE   vsoicl.PRODUCT_LINE <> 'MIRR'
                            AND Product_Family IS NOT NULL
                            AND Product_Family <> 'NULL'
                    GROUP BY CONFIRMED_TO ,
                            Product_Family
                  ) AS f ON q.surgeon_name = f.Surgeon_Name
                            AND q.Product_Family = f.Product_Family
ORDER BY Surgeon_Name ,
        Product_Family ,
        Year ,
        Quarter

非常感谢任何帮助。

我昨晚才知道。

select 
snyq.Surgeon_Name,
snyq.Product_Family,
f.First_Date,
snyq.Year,
snyq.Quarter,
sn_sales.[Monthly_Average]
from
(
select * from

    (select distinct rtrim(confirmed_to) as 'Surgeon_Name'
    ,Product_Family

    from Vsoicl
    left join Product_Line_Desc 
    on vsoicl.PART_ID = Product_Line_Desc.Part_ID 

    where vsoicl.PRODUCT_LINE <> 'MIRR'
    and Product_Family is not null
    and Product_Family <> 'NULL'
    and rev_ship_date between '2013-01-01' and GETDATE()

    Group by CONFIRMED_TO, Product_Family) sn, 

(
select distinct YEAR(rev_ship_date) as Year, datepart(QUARTER,REV_SHIP_DATE) as Quarter
    from vsoicl
    where REV_SHIP_DATE between '2013-01-01' and GETDATE()) yq
) snyq
left join 
(
    select q.Surgeon_Name
,q.Product_Family  
,q.Year 
,q.Quarter 
,cast(round(q.Monthly_Average,2) as money) as 'Monthly_Average'

from (select distinct rtrim(confirmed_to) as 'Surgeon_Name'
,Product_Family
,year(rev_ship_date) as 'Year'
,DATENAME(Quarter, CAST(REV_SHIP_DATE AS DATETIME)) as 'Quarter'
,(SUM(amount) / 3) as 'Monthly_Average'

from Vsoicl
left join Product_Line_Desc 
on vsoicl.PART_ID = Product_Line_Desc.Part_ID 

where vsoicl.PRODUCT_LINE <> 'MIRR'
and Product_Family is not null
and Product_Family <> 'NULL'
and CONFIRMED_TO <> ''
and REV_SHIP_DATE >= '2013-01-01'

Group by CONFIRMED_TO, Product_Family, YEAR(rev_ship_date), DATENAME(Quarter, CAST(REV_SHIP_DATE AS DATETIME))) as q
 ) sn_sales
on snyq.Surgeon_Name=sn_sales.Surgeon_Name and snyq.Product_Family=sn_sales.Product_Family and snyq.Year=sn_sales.Year and snyq.Quarter=sn_sales.Quarter 
left join (select distinct rtrim(confirmed_to) as 'Surgeon_Name'
,Product_Family
,cast(MIN(rev_ship_date) as date) as 'First_Date'

from Vsoicl
left join Product_Line_Desc 
on vsoicl.PART_ID = Product_Line_Desc.Part_ID 

where vsoicl.PRODUCT_LINE <> 'MIRR'
and Product_Family is not null
and Product_Family <> 'NULL'
and (STORES_CODE <> 'QU' and SO_STATUS <> 'X' and SO_LINE_STATUS <> 'X' and SHIP_TYPE not IN('O', 'C'))
and (CUST_PO_ID not like '%Demo%' and CUST_PO_ID not like '%expired%' and CUST_PO_ID not like '%literature%' and CUST_PO_ID not like '%toss%' and CUST_PO_ID not like '%replace%' and CUST_PO_ID not like '%swap%' and CUST_PO_ID not like '%exchange%' and CUST_PO_ID not like '%cancel%' and CUST_PO_ID not like '%duplicate%')
and ORDER_CLASS <> 'R'

Group by CONFIRMED_TO, Product_Family) as f
on snyq.Surgeon_Name=f.Surgeon_Name and snyq.Product_Family=f.Product_Family 
order by Surgeon_Name,Product_Family,Year,Quarter

1 个答案:

答案 0 :(得分:1)

我在haste中读过sql,修改过的想法是

为所有感兴趣的年/季度创建myCalendar表(myYYYY,myQQ)。这将是一个小桌子,10年只有40行

然后使用交叉连接来&#34;乘以&#34;每个YYYYQQ的外科医生/产品

SELECT
    just.Surgeon_Name ,
    just.Product_Family ,

    myYYYY ,
    myQQ ,

    First_Date ,
    [Monthly Average]

FROM  (
    (SELECT  DISTINCT
                RTRIM(confirmed_to) AS 'Surgeon_Name' ,
                Product_Family ,
      FROM      Vsoicl
      WHERE     PRODUCT_LINE <> 'MIRR'
            AND Product_Family IS NOT NULL
            AND Product_Family <> 'NULL'
            AND CONFIRMED_TO <> ''
            AND REV_SHIP_DATE >= '2013-01-01'  
    ) as  just

 ,  myCalendar
       )

LEFT JOIN
    (the above sql) as myV
     ON    just.Surgeon_Name = myV.Surgeon_Name
     and   just.Product_Family= myV.Product_Family
     and   myYYYY = Year
     and   myQQ = Quarter