如何从SQL Server有条件地选择记录

时间:2016-06-24 15:28:23

标签: sql sql-server sql-server-2008

我有一个SQL问题,我可以使用帮助。我正在使用SQL Server 2008。

用例如下。我们有一个用户观看视频的系统,每次用户观看视频时,我们都会记录该活动。我们每次捕获三个属性; assetid(资产是视频),customerid和status。

记录可以有三种不同的状态; '完成','玩'和'开始'。

编写系统的这一部分的人不是开发人员,而不是更新现有记录的状态,每次用户观看视频时插入新的重复记录。因此,我们有数千条重复记录。这是一个示例数据集

enter image description here

我需要解决的问题是通过assetid,customerid和status选择记录。我需要选择状态为“完成”的记录(如果存在)。

如果记录的状态为“正在播放”,但没有相同的assetid记录和状态为“完成”的customerid,则选择该记录。

如果记录的状态为“开始”,但没有相同的assetid记录和状态为“完成”或“正在播放”的customerid,则选择该记录。

以下是我尝试使用CASE语句解决问题的示例代码。我还尝试了另一个带有NOT IN子查询的case语句,但没有成功。

INSERT INTO #ViewTime (AssetID, CustomerID, ViewTime)
SELECT 
     tt.customerid, tt.assetId, tt.assetstatus, 
    CASE WHEN 
        tt.AssetStatus = 'COMPLETION' 
    AND 
        ISNUMERIC(timeposition) = 1 
    THEN 
        CONVERT(Numeric(18,3), timePosition)
    WHEN 
        tt.AssetStatus = 'PLAYING'
    AND 
        ISNUMERIC(timeposition) = 1 
    THEN 
        CONVERT(Numeric(18,3), timePosition)
    WHEN 
        tt.AssetStatus = 'START' 
    AND 
        ISNUMERIC(timeposition) = 1 
    THEN 
        CONVERT(Numeric(18,3), timePosition)
    ELSE null
    END AS ViewTime
FROM 
    TableAssetTracking tt
    inner join TableAssets ta
    on tt.AssetID = ta.AssetID
WHERE 
    tt.timePosition is not null
AND 
    AssetBuffering is null

任何建议都将不胜感激。谢谢,德里克

3 个答案:

答案 0 :(得分:1)

我需要解决的问题是通过assetid,customerid和status选择记录。

我需要选择状态为“完成”的记录(如果存在)。

select distinct assetID, CustomerID  
  from table 
 where status = 'complete' 

如果记录的状态为“正在播放”,但没有相同的assetid记录和状态为“完成”的customerid,则选择该记录。

select assetID, CustomerID  
  from table 
 where status = 'playing'
except
select assetID, CustomerID  
  from table 
 where status = 'complete'

如果记录的状态为“开始”,但没有相同的assetid记录和状态为“完成”或“正在播放”的customerid,则选择该记录。

select assetID, CustomerID  
  from table 
 where status = 'start'
except
select assetID, CustomerID  
  from table 
 where status in ('complete', 'playing') 

以上不会给你我在示例中看到的ViewTime 它不在要求声明中

select * 
from 
(  select assetID, CustomerID, status, ViewTime 
        , row_number() over (partition by assetID, CustomerID order by status, ViewTime desc) as rn
     from table 
    where status in ('complete', 'playing', 'start') 
) tt 
where tt.rn = 1

答案 1 :(得分:1)

有很多方法可以做到这一点。这是一个。

我将使用psuedocode,因为示例代码中的表与您问题中的描述不匹配。你必须将这种技术应用到你的桌子上。

SELECT DISTINCT t.AssetId, t.CustomerId, (
  SELECT TOP 1 Status
  FROM MyTable t1
  WHERE t1.AssetId=t.AssetId
  AND t1.CustomerId=t.CustomerId
  ORDER BY CASE t1.Status
   WHEN 'Completion' THEN 0
   WHEN 'Playing' THEN 1
   WHEN 'Started' THEN 2
   ELSE 3
  END ASC
) AS Status
FROM MyTable t

答案 2 :(得分:1)

我这样做是为了向您展示一种查看数据的广泛方式。您希望真正识别为每个人和视频插入表格的最后一条记录。所以我们得到最后一个,然后得到该记录的状态。

IF OBJECT_ID('tempdb..#lastRecord') IS NOT NULL DROP TABLE #lastRecord

    SELECT
        max(trackingassetdatecreated) dt,
        assetid,
        customerid,
    INTO #lastRecord
    FROM 
        TableAssetTracking
    GROUP BY
        assetid,
        customerid

    SELECT
        t.assetstatus,
        lr.*
    FROM
        TableAssetTracking t
    INNER JOIN
        #lastRecord lr on
            lr.trackingassetdatecreated = t.trackingassetdatecreated
            and lr.assetid = t.assetid
            and lr.customerid = t.customerid