Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/74.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 基于同一子集内的值从子集中选择?_Sql_Sql Server_Sql Server 2008_Select - Fatal编程技术网

Sql 基于同一子集内的值从子集中选择?

Sql 基于同一子集内的值从子集中选择?,sql,sql-server,sql-server-2008,select,Sql,Sql Server,Sql Server 2008,Select,我创建了一个如下表: CREATE TABLE #TEMP(RecordDate datetime, First VARCHAR(255), Last VARCHAR(255), Value int) INSERT INTO #TEMP VALUES('2011-03-01 00:00:00.000','john','smith','10') INSERT INTO #TEMP VALUES('2011-03-01 00:00:00.000','john','adams','60') INSE

我创建了一个如下表:

CREATE TABLE #TEMP(RecordDate datetime, First VARCHAR(255), Last VARCHAR(255), Value int)

INSERT INTO #TEMP VALUES('2011-03-01 00:00:00.000','john','smith','10')
INSERT INTO #TEMP VALUES('2011-03-01 00:00:00.000','john','adams','60')
INSERT INTO #TEMP VALUES('2011-03-01 00:00:00.000','john','resig','90')
INSERT INTO #TEMP VALUES('2011-03-01 00:00:00.000','john','balte','95')

INSERT INTO #TEMP VALUES('2011-03-01 01:00:00.000','john','smith','98')
INSERT INTO #TEMP VALUES('2011-03-01 01:00:00.000','john','adams','67')
INSERT INTO #TEMP VALUES('2011-03-01 01:00:00.000','john','resig','24')
INSERT INTO #TEMP VALUES('2011-03-01 01:00:00.000','john','balte','20')

SELECT * FROM #TEMP

DROP TABLE #TEMP
其中现在包含以下记录:

RecordDate              First   Last    Value
2011-03-01 00:00:00.000 john    smith   10
2011-03-01 00:00:00.000 john    adams   60
2011-03-01 00:00:00.000 john    resig   90
2011-03-01 00:00:00.000 john    balte   95
2011-03-01 01:00:00.000 john    smith   98
2011-03-01 01:00:00.000 john    adams   67
2011-03-01 01:00:00.000 john    resig   24
2011-03-01 01:00:00.000 john    balte   20
我正在尝试获得如下表:

RecordDate                first    Good     Bad
2011-03-01 00:00:00.000   john     3        1
2011-03-01 01:00:00.000   john     2        2
我计算好的和坏的方法是,取特定日期名字为john的所有人的最大值,然后将其作为特定日期和名字的原始数据集的过滤器。只有大于0.5*MAXValue的值才视为良好

在结果表中,有3个好值,因为第一个日期的最大值为95,只有60,90,95大于0.5*95,因此结果为good,Bad=3,1。在第二个结果中,同样是2,2

我的表足够大,有近3亿条记录,我不知道从哪里开始有效地执行这项操作。有没有关于高效方式的建议

我目前的工作方法但成本高昂,如下所示:

SELECT    RecordDate
        , FirstName
        , 
        (
            SELECT COUNT(*) 
            FROM #TEMP
            WHERE Value > 0.5*(SELECT MAX(Value) FROM #TEMP WHERE RecordDate = A.RecordDate AND FirstName = A.FirstName)
            AND RecordDate = A.RecordDate AND FirstName = A.FirstName
        ) AS Good
        ,
        (
            SELECT COUNT(*) 
            FROM #TEMP
            WHERE Value < 0.5*(SELECT MAX(Value) FROM #TEMP WHERE RecordDate = A.RecordDate AND FirstName = A.FirstName)
            AND RecordDate = A.RecordDate AND FirstName = A.FirstName
        ) AS Bad
FROM #TEMP A
GROUP BY RecordDate, FirstName;
给你:

select 
   t.RecordDate,
   COUNT(case 
           when t.Value > MV.MaxValue * 0.5 then 1
           else null
         end) Good,
   COUNT(case 
           when t.Value <= MV.MaxValue * 0.5 then 1
           else null
         end) Bad
from #Temp t inner join
(select RecordDate, MAX(Value) MaxValue
 from #Temp Group By RecordDate) MV on t.RecordDate = MV.RecordDate
Group by t.RecordDate
给你:

select 
   t.RecordDate,
   COUNT(case 
           when t.Value > MV.MaxValue * 0.5 then 1
           else null
         end) Good,
   COUNT(case 
           when t.Value <= MV.MaxValue * 0.5 then 1
           else null
         end) Bad
from #Temp t inner join
(select RecordDate, MAX(Value) MaxValue
 from #Temp Group By RecordDate) MV on t.RecordDate = MV.RecordDate
Group by t.RecordDate

引用外部查询的嵌套查询可能会导致大量重复工作。 这将一次性计算所有姓名和日期的最大值:

SELECT RecordDate, FirstName, MAX(Value) FROM #TEMP GROUP BY RecordDate, FirstName  
现在连接回原始数据:

SELECT A.RecordDate, A.FirstName,
       SUM(CASE WHEN Value > MaxVal*0.5 THEN 1 ELSE 0 END) AS GOOD,
       SUM(CASE WHEN Value > MaxVal*0.5 THEN 0 ELSE 1 END) AS BAD,
FROM #TEMP A INNER JOIN
     (SELECT RecordDate, FirstName, MAX(Value) as MaxVal 
      FROM #TEMP GROUP BY RecordDate, FirstName) B 
         ON (A.RecordDate = B.RecordDate AND A.FirstName = B.FirstName)
GROUP BY A.RecordDate, A.FirstName

引用外部查询的嵌套查询可能会导致大量重复工作。 这将一次性计算所有姓名和日期的最大值:

SELECT RecordDate, FirstName, MAX(Value) FROM #TEMP GROUP BY RecordDate, FirstName  
现在连接回原始数据:

SELECT A.RecordDate, A.FirstName,
       SUM(CASE WHEN Value > MaxVal*0.5 THEN 1 ELSE 0 END) AS GOOD,
       SUM(CASE WHEN Value > MaxVal*0.5 THEN 0 ELSE 1 END) AS BAD,
FROM #TEMP A INNER JOIN
     (SELECT RecordDate, FirstName, MAX(Value) as MaxVal 
      FROM #TEMP GROUP BY RecordDate, FirstName) B 
         ON (A.RecordDate = B.RecordDate AND A.FirstName = B.FirstName)
GROUP BY A.RecordDate, A.FirstName

谢谢你的把戏。我需要按名字对结果进行分组,因此我编辑了您的答案以反映这一点。你介意看一下吗?如果不正确,我将恢复更改。太好了!我很高兴你在我完成我的回答之前发布了你的答案;我正在使用NTILE2,您的回答让我重新检查问题的内容:+是的,我一直很乐意帮忙!谢谢你的把戏。我需要按名字对结果进行分组,因此我编辑了您的答案以反映这一点。你介意看一下吗?如果不正确,我将恢复更改。太好了!我很高兴你在我完成我的回答之前发布了你的答案;我正在使用NTILE2,您的回答让我重新检查问题的内容:+是的,我一直很乐意帮忙!但仍然是+1感谢您的时间。请注意,这使用的是SUM1或0,而不是COUNT1或NULL。您确定NULL不会添加到计数中吗?它会发生:。您的解决方案因使用SUM而有所不同,但它也有效。你应该留下它,因为它可能会帮助未来的访问者。嗯,不。我在内存中工作,没有服务器可以测试。嗯,因为OP发布了代码来实际创建结构和数据,所以我很容易实际运行查询。我可以告诉你,我发布的代码运行平稳:而且,理论上讲,COUNT不应该为null,但仍然是+1感谢您的时间。请注意,这使用的是SUM1或0,而不是COUNT1或NULL。您确定NULL不会添加到计数中吗?它会发生:。您的解决方案因使用SUM而有所不同,但它也有效。你应该留下它,因为它可能会帮助未来的访问者。嗯,不。我在内存中工作,没有服务器可以测试。嗯,因为OP发布了代码来实际创建结构和数据,所以我很容易实际运行查询。我可以告诉你我发布的代码运行顺利:而且,从理论上讲,COUNT不应该计算空值