如果两个特定值出现在同一天的总和值

时间:2017-09-26 04:10:20

标签: tsql sql-server-2014

我有一个数据集,按日期按武器类型收获物种。下面的数据集示例:

Species  Total  HarvestMonthDayYear  WeaponID  WeaponType
Deer     623    1/14/2017            1         Gun
Deer     10     1/14/2017            3         Reg Bow
Deer     15     1/14/2017            4         Crossbow
Deer     5      9/20/2017            4         Crossbow
Deer     9      9/21/2017            2         Muzzleloader
Deer     2      9/21/2017            3         Reg Bow
Deer     1      9/21/2017            4         Crossbow
Deer     1      9/21/2017            8         Shotgun
Deer     10     9/22/2017            1         Gun
Deer     1      9/22/2017            3         Reg Bow

我要做的是,当“Reg Bow”和“Crossbow”在同一天收获时,我想将结果合并到一行名为“Archery”。最终的数据集应如下所示:

Species Total  HarvestMonthDayYear  WeaponID  WeaponType
Deer    623    1/14/2017            1         Gun
Deer    25     1/14/2017            10        Archery
Deer    5      9/20/2017            4         Crossbow
Deer    9      9/21/2017            2         Muzzleloader
Deer    3      9/21/2017            10        Archery
Deer    1      9/21/2017            8         Shotgun
Deer    10     9/22/2017            1         Gun
Deer    1      9/22/2017            2         Muzzleloader
Deer    1      9/22/2017            3         Reg Bow

2017年1月14日和2017年9月22日 - 常规的弓和弩被用来收割鹿,所以我想将它们组合成一套 - 但是在09/20/20和09/22/2017 - 只使用了弩或常规弓,所以这个结果应保留原样。

这可能吗?我想不出一种开始编码的方法。

3 个答案:

答案 0 :(得分:1)

你可以将其称为联盟:

WITH cte AS (
    SELECT Species, HarvestMonthDayYear, SUM(Total) AS Total
    FROM yourTable
    WHERE
        WeaponType IN ('Reg Bow', 'Crossbow')
    GROUP BY
        Species, HarvestMonthDayYear
    HAVING COUNT(DISTINCT WeaponType) = 2
)
SELECT
    t1.Species, t1.Total, t1.HarvestMonthDayYear, t1.WeaponID, t1.WeaponType
FROM yourTable t1
LEFT JOIN cte t2
    ON t1.Species = t2.Species AND
       t1.HarvestMonthDayYear = t2.HarvestMonthDayYear
WHERE
    t2.Species IS NULL OR
    (t2.Species IS NOT NULL AND WeaponType NOT IN ('Reg Bow', 'Crossbow'))
UNION ALL
SELECT
    Species, Total, HarvestMonthDayYear, 10, 'Archery'
FROM cte;

在这里演示:

Rextester

答案 1 :(得分:1)

没有TCE:

SELECT Species, HarvestMonthDayYear, SUM(Total) AS Total
    , CASE WHEN WeaponType IN ('Reg Bow', 'Crossbow') THEN 10 ELSE WeaponID END AS WeaponID
    , MAX(CASE WHEN WeaponType IN ('Reg Bow', 'Crossbow') THEN 'Archery' ELSE WeaponType END) AS WeaponType 
FROM yourTable
GROUP BY
     Species, HarvestMonthDayYear
     , (CASE WHEN WeaponType IN ('Reg Bow', 'Crossbow') THEN 10 ELSE WeaponID END)

答案 2 :(得分:0)

这应该可以满足您的需求,使用CTE但不使用UNION(经过测试)并且性能稍高......

WITH HarvestResults AS
(
SELECT  Species,
        Total,
        HarvestMonthDayYear,
        CASE WHEN WeaponType IN ('Crossbow','Reg Bow') THEN 10 ELSE WeaponID END AS WeaponID,
        WeaponType,
        LAG(HarvestMonthDayYear,1) OVER(ORDER BY Species,HarvestMonthDayYear) AS PrevHarvestDate,
        LEAD(HarvestMonthDayYear,1) OVER(ORDER BY Species,HarvestMonthDayYear) AS NextHarvestDate,
        LAG(WeaponType,1) OVER(ORDER BY Species,HarvestMonthDayYear) AS PrevWeaponType,
        LEAD(WeaponType,1) OVER(ORDER BY Species,HarvestMonthDayYear) AS NextWeponType
FROM dbo.Harvest
)
SELECT  Species,
        SUM(Total) AS TOTAL,
        HarvestMonthDayYear,
        CASE WHEN WeaponType IN ('Crossbow','Reg Bow') 
             AND ((PrevHarvestDate = HarvestMonthDayYear OR NextHarvestDate = HarvestMonthDayYear)
             AND  (PrevWeaponType IN ('Crossbow','Reg Bow') OR NextWeponType IN ('Crossbow','Reg Bow')))
             THEN 10 ELSE WeaponID END AS WeaponID,
        CASE WHEN WeaponType IN ('Crossbow','Reg Bow') 
             AND ((PrevHarvestDate = HarvestMonthDayYear OR NextHarvestDate = HarvestMonthDayYear)
             AND  (PrevWeaponType IN ('Crossbow','Reg Bow') OR NextWeponType IN ('Crossbow','Reg Bow')))
             THEN 'Archery' ELSE WeaponType END AS WeaponType
FROM HarvestResults
GROUP BY Species,
         HarvestMonthDayYear,
         CASE WHEN WeaponType IN ('Crossbow','Reg Bow') 
              AND ((PrevHarvestDate = HarvestMonthDayYear OR NextHarvestDate = HarvestMonthDayYear)
              AND  (PrevWeaponType IN ('Crossbow','Reg Bow') OR NextWeponType IN ('Crossbow','Reg Bow')))
              THEN 10 ELSE WeaponID END,
         CASE WHEN WeaponType IN ('Crossbow','Reg Bow') 
              AND ((PrevHarvestDate = HarvestMonthDayYear OR NextHarvestDate = HarvestMonthDayYear)
              AND  (PrevWeaponType IN ('Crossbow','Reg Bow') OR NextWeponType IN ('Crossbow','Reg Bow')))
              THEN 'Archery' ELSE WeaponType END
ORDER BY Species,
         HarvestMonthDayYear,
         WeaponID,
         WeaponType;