我正在将此数据作为转换过程的一部分插入另一个表中。不幸的是,我无法在源位置或目标位置修改表架构。
架构如下(超级简化,但数据类型不能修改,只是显然是强制转换)
NullPointerException
我有以下源数据:(显然只是一个人的数据快照)
CREATE TABLE [dbo].[TestScores](
[id] [INT] NOT NULL,
[EXAMNE_ID] [VARCHAR](40) NULL,
[TestName] VARCHAR(30) NULL,
[PASS_STA] [VARCHAR](5) NULL,
[TST_DTE] [VARCHAR](8) NULL,
[STD_SCOR] [VARCHAR](3) NULL,
) ON [PRIMARY]
我的最终结果目标数据应如下所示:
+----+-----------+-----------------+----------+----------+----------+
| id | EXAMNE_ID | TestName | PASS_STA | TST_DTE | STD_SCOR |
+----+-----------+-----------------+----------+----------+----------+
| 1 | 00001 | Social Studies | Fail | 20160608 | 7 |
| 2 | 00001 | Science | Fail | 20160608 | 8 |
| 3 | 00001 | Reading | Fail | 20160608 | 2 |
| 4 | 00001 | Math | Fail | 20160608 | 8 |
| 5 | 00001 | Writing | Fail | 20160608 | 7 |
| 6 | 00001 | Social Studies | Fail | 20160608 | 7 |
| 7 | 00001 | Science | Fail | 20160608 | 8 |
| 8 | 00001 | Reading | Fail | 20160608 | 2 |
| 9 | 00001 | Math | Fail | 20160608 | 8 |
| 10 | 00001 | Writing | Fail | 20160608 | 7 |
| 11 | 00001 | Social Studies | Fail | 20160608 | 7 |
| 12 | 00001 | Science | Fail | 20160608 | 8 |
| 13 | 00001 | Reading | Fail | 20160608 | 2 |
| 14 | 00001 | Math | Fail | 20160608 | 8 |
| 15 | 00001 | Writing | Fail | 20160608 | 7 |
| 16 | 00001 | Social Studies | Fail | 20160608 | 7 |
| 17 | 00001 | Social Studies | Fail | 20160930 | 10 |
| 18 | 00001 | Science | Fail | 20160608 | 8 |
| 19 | 00001 | Reading | Fail | 20160608 | 2 |
| 20 | 00001 | Reading | Fail | 20160930 | 5 |
| 21 | 00001 | Math | Fail | 20160608 | 8 |
| 22 | 00001 | Writing | Fail | 20160608 | 7 |
| 23 | 00001 | Writing | Fail | 20160930 | 10 |
| 24 | 00001 | Social Studies | Fail | 20160608 | 7 |
| 25 | 00001 | Social Studies | Fail | 20160930 | 10 |
| 26 | 00001 | Science | Fail | 20160608 | 8 |
| 27 | 00001 | Reading | Fail | 20160608 | 2 |
| 28 | 00001 | Reading | Fail | 20160930 | 5 |
| 29 | 00001 | Math | Fail | 20160608 | 8 |
| 30 | 00001 | Writing | Fail | 20160608 | 7 |
| 31 | 00001 | Writing | Fail | 20160930 | 10 |
| 32 | 00001 | Social Studies | Fail | 20160608 | 7 |
| 33 | 00001 | Social Studies | Fail | 20160930 | 10 |
| 34 | 00001 | Science | Fail | 20160608 | 8 |
| 35 | 00001 | Reading | Fail | 20160608 | 2 |
| 36 | 00001 | Reading | Fail | 20160930 | 5 |
| 37 | 00001 | Math | Fail | 20160608 | 8 |
| 38 | 00001 | Writing | Pass | 20160608 | 7 |
| 39 | 00001 | Writing | Pass | 20160930 | 10 |
| 40 | 00001 | Social Studies | Pass | 20160608 | 7 |
| 41 | 00001 | Social Studies | Pass | 20160930 | 10 |
| 42 | 00001 | Science | Pass | 20160608 | 8 |
| 43 | 00001 | Reading | Pass | 20160608 | 2 |
| 44 | 00001 | Reading | Pass | 20160930 | 5 |
| 45 | 00001 | Reading | Pass | 20161202 | 9 |
| 46 | 00001 | Math | Pass | 20160608 | 8 |
+----+-----------+-----------------+----------+----------+----------+
我知道我提供了大量的额外数据,因为我只是在寻找PASS_STA为'Pass'的结果,但我想提供更多完整的图片。
基本上,出现的逻辑是,对于给定的人,当考试通过时,拉出TST_DTE和STD_SCOR列的最大值。我正在尝试使用看起来像max的多个变体,但它朝着错误的方向前进。
目前这个查询并没有给我我正在寻找的东西。
+----+-----------+-----------------+----------+----------+----------+
| id | EXAMNE_ID | TestName | PASS_STA | TST_DTE | STD_SCOR |
+----+-----------+-----------------+----------+----------+----------+
| 39 | 00001 | Writing | Pass | 20160930 | 10 |
| 41 | 00001 | Social Studies | Pass | 20160930 | 10 |
| 42 | 00001 | Science | Pass | 20160608 | 8 |
| 45 | 00001 | Reading | Pass | 20161202 | 9 |
| 46 | 00001 | Math | Pass | 20160608 | 8 |
+----+-----------+-----------------+----------+----------+----------+
部分我认为我需要嵌套查询,因为我正在寻找两个最大值(加上一个是日期 - 好吧,日期,因为它在varchar中),另一个是数字(但同样,存储在varchar中)或者可能以某种方式存储RANK功能?
我宁愿不必为五个主题领域中的每一个做集合CASE陈述。实际上总共有几十个主题领域,我在这里展示的这一个测试类型有五个。因此,虽然我认为汇总案例陈述可能有效,但可能过于繁琐。
有什么想法吗?
提前致谢
答案 0 :(得分:1)
除数据类型问题外,您需要从您的论坛中删除std_scor
,然后将having
移至where
:
根据您的日期格式,无需将tst_dte
转换为date
或int
,但无论如何我都包含了转化。
select
examne_id
, pass_sta
, TestName
, max(convert(date,tst_dte)) as tst_dte
, max(convert(int,std_scor)) as std_scor
from dbo.TestScores
group by
examne_id
, pass_sta
, TestName
having pass_sta = 'Pass'
rextester演示:http://rextester.com/BDI16678
返回:
+-----------+----------+----------------+------------+----------+
| examne_id | pass_sta | TestName | tst_dte | std_scor |
+-----------+----------+----------------+------------+----------+
| 1 | Pass | Math | 2016-06-08 | 8 |
| 1 | Pass | Reading | 2016-12-02 | 9 |
| 1 | Pass | Science | 2016-06-08 | 8 |
| 1 | Pass | Social Studies | 2016-09-30 | 10 |
| 1 | Pass | Writing | 2016-09-30 | 10 |
+-----------+----------+----------------+------------+----------+
答案 1 :(得分:1)
;With cte(id , EXAMNE_ID , TestName , PASS_STA , TST_DTE , STD_SCOR )
AS
(
SELECT 1 , '00001' , 'Social Studies' , 'Fail' , '20160608', 7 Union all
SELECT 2 , '00001' , 'Science' , 'Fail' , '20160608', 8 Union all
SELECT 3 , '00001' , 'Reading' , 'Fail' , '20160608', 2 Union all
SELECT 4 , '00001' , 'Math' , 'Fail' , '20160608', 8 Union all
SELECT 5 , '00001' , 'Writing' , 'Fail' , '20160608', 7 Union all
SELECT 6 , '00001' , 'Social Studies' , 'Fail' , '20160608', 7 Union all
SELECT 7 , '00001' , 'Science' , 'Fail' , '20160608', 8 Union all
SELECT 8 , '00001' , 'Reading' , 'Fail' , '20160608', 2 Union all
SELECT 9 , '00001' , 'Math' , 'Fail' , '20160608', 8 Union all
SELECT 10 , '00001' , 'Writing' , 'Fail' , '20160608', 7 Union all
SELECT 11 , '00001' , 'Social Studies' , 'Fail' , '20160608', 7 Union all
SELECT 12 , '00001' , 'Science' , 'Fail' , '20160608', 8 Union all
SELECT 13 , '00001' , 'Reading' , 'Fail' , '20160608', 2 Union all
SELECT 14 , '00001' , 'Math' , 'Fail' , '20160608', 8 Union all
SELECT 15 , '00001' , 'Writing' , 'Fail' , '20160608', 7 Union all
SELECT 16 , '00001' , 'Social Studies' , 'Fail' , '20160608', 7 Union all
SELECT 17 , '00001' , 'Social Studies' , 'Fail' , '20160930', 10 Union all
SELECT 18 , '00001' , 'Science' , 'Fail' , '20160608', 8 Union all
SELECT 19 , '00001' , 'Reading' , 'Fail' , '20160608', 2 Union all
SELECT 20 , '00001' , 'Reading' , 'Fail' , '20160930', 5 Union all
SELECT 21 , '00001' , 'Math' , 'Fail' , '20160608', 8 Union all
SELECT 22 , '00001' , 'Writing' , 'Fail' , '20160608', 7 Union all
SELECT 23 , '00001' , 'Writing' , 'Fail' , '20160930', 10 Union all
SELECT 24 , '00001' , 'Social Studies' , 'Fail' , '20160608', 7 Union all
SELECT 25 , '00001' , 'Social Studies' , 'Fail' , '20160930', 10 Union all
SELECT 26 , '00001' , 'Science' , 'Fail' , '20160608', 8 Union all
SELECT 27 , '00001' , 'Reading' , 'Fail' , '20160608', 2 Union all
SELECT 28 , '00001' , 'Reading' , 'Fail' , '20160930', 5 Union all
SELECT 29 , '00001' , 'Math' , 'Fail' , '20160608', 8 Union all
SELECT 30 , '00001' , 'Writing' , 'Fail' , '20160608', 7 Union all
SELECT 31 , '00001' , 'Writing' , 'Fail' , '20160930', 10 Union all
SELECT 32 , '00001' , 'Social Studies' , 'Fail' , '20160608', 7 Union all
SELECT 33 , '00001' , 'Social Studies' , 'Fail' , '20160930', 10 Union all
SELECT 34 , '00001' , 'Science' , 'Fail' , '20160608', 8 Union all
SELECT 35 , '00001' , 'Reading' , 'Fail' , '20160608', 2 Union all
SELECT 36 , '00001' , 'Reading' , 'Fail' , '20160930', 5 Union all
SELECT 37 , '00001' , 'Math' , 'Fail' , '20160608', 8 Union all
SELECT 38 , '00001' , 'Writing' , 'Pass' , '20160608', 7 Union all
SELECT 39 , '00001' , 'Writing' , 'Pass' , '20160930', 10 Union all
SELECT 40 , '00001' , 'Social Studies' , 'Pass' , '20160608', 7 Union all
SELECT 41 , '00001' , 'Social Studies' , 'Pass' , '20160930', 10 Union all
SELECT 42 , '00001' , 'Science' , 'Pass' , '20160608', 8 Union all
SELECT 43 , '00001' , 'Reading' , 'Pass' , '20160608', 2 Union all
SELECT 44 , '00001' , 'Reading' , 'Pass' , '20160930', 5 Union all
SELECT 45 , '00001' , 'Reading' , 'Pass' , '20161202', 9 Union all
SELECT 46 , '00001' , 'Math' , 'Pass' , '20160608', 8
)
SELECT id
,EXAMNE_ID
,TestName
,PASS_STA
,TST_DTE
,STD_SCOR
FROM (
SELECT *
,ROW_NUMBER() OVER (
PARTITION BY TestName ORDER BY id DESC
) AS Rno
FROM (
SELECT *
,ROW_NUMBER() OVER (
PARTITION BY TestName
,TST_DTE ORDER BY id DESC
) AS Seq
FROM cte
) Dt
WHERE Dt.Seq = 1
AND PASS_STA = 'Pass'
) dt2
WHERE dt2.Rno = 1
ORDER BY dt2.id ASC
输出
+----+-----------+-----------------+----------+----------+----------+
| id | EXAMNE_ID | TestName | PASS_STA | TST_DTE | STD_SCOR |
+----+-----------+-----------------+----------+----------+----------+
| 39 | 00001 | Writing | Pass | 20160930 | 10 |
| 41 | 00001 | Social Studies | Pass | 20160930 | 10 |
| 42 | 00001 | Science | Pass | 20160608 | 8 |
| 45 | 00001 | Reading | Pass | 20161202 | 9 |
| 46 | 00001 | Math | Pass | 20160608 | 8 |
+----+-----------+-----------------+----------+----------+----------+
答案 2 :(得分:0)
对每位学生的记录进行排名,并按日期与ROW_NUMBER
进行测试。然后只记录每个学生的最新日期和考试(即排名第一的记录)。
select examne_id, pass_sta, testname, tst_dte, std_scor
from
(
select
ts.*,
row_number() over (partition by examne_id, testname order by tst_dte desc) as rn
from dbo.testscores ts
where pass_sta = 'Pass'
)
where rn = 1;