我有以下3个表格:
A) Unit information [Unit]
+-----------+---------+-------+
| record_ID | SN | Data1 |
+-----------+---------+-------+
| 1 | 123 123 | info |
+-----------+---------+-------+
B) Test related information [TestingData]
+---------+------------------+-----------+
| SN | Info1 | Data1 |
+---------+------------------+-----------+
| 123 123 | Some information | Some data |
+---------+------------------+-----------+
C) Join table to more testing information [Link]
+--------+---------+
| LinkID | SN |
+--------+---------+
| 1 | 123 123 |
+--------+---------+
D) Testing details [Tests]
+--------+---------------------+-----------+
| LinkID | testdate | Testname |
+--------+---------------------+-----------+
| 1 | 10.05.2015 22:22:00 | AD1 |
+--------+---------------------+-----------+
现在是棘手的部分:
我需要获取每个LinkID的最后一条记录,例如测试名称= AD1。
我设法创建了一个只执行此操作的查询,除非在没有名为test的AD1的情况下不返回任何行:
SELECT * FROM (
SELECT
ROW_NUMBER() OVER(PARTITION BY rf2.linkID ORDER BY rf2.testDate DESC) AS rn
,rf2.*, rs.*
FROM dbo.Unit rs
FULL OUTER JOIN dbo.TestingData rf ON ( rs.SN = rf.SN )
FULL OUTER JOIN dbo.Link rf1 ON ( rf.SN = rf1.SN)
FULL OUTER JOIN dbo.Tests rf2 ON ( rf1.linkID = rf2.linkID )
WHERE rf2.testType = 'AD1'
) T
WHERE rn = 1
ORDER BY SN ASC;
如何在查询上方扩展(如果可能的话)以便在没有AD1的testType的情况下获取具有空值的行?
这背后的原因是我需要将此部分集成到更大的报告中,我将通过SN上的联接进行整合。
答案 0 :(得分:1)
我需要获取每个LinkID的最后一条记录,例如测试名称= AD1。
当一张表格中包含您需要的所有信息时,我无法弄清楚为什么您的问题会引用四个表格。 full join
更难解释。
这会获得您想要的tests
行:
select top (1) with ties t.*
from tests t
where t.testName = 'AD1'
order by row_number() over (partition by t.linkid order by t.testdate desc)
union all
select t.*
from tests t
where not exists (select 1 from tests t2 where t2.linkid = t.linkid and t.testName = 'AD1');
您也可以使用窗口功能执行此操作:
select t.*
from (select t.*,
row_number() over (partition by linkid, testname order by testdate desc) as seqnum,
sum(case when testName = 'AD1' then 1 else 0 end) over (partition by linkid) as num_ad1
from tests t
) t
where (l.num_ad1 > 0 and testName = 'AD1' and seqnum = 1) or
(l.num_ad1 = 0);
您可以在其他表格中加入,以获取您可能需要的其他列。不需要FULL JOIN
,LEFT JOIN
就足够了。
答案 1 :(得分:0)
您说的是where test name = AD1
所以我认为您应该在Testname
子句中检查testType
而不是WHERE
,如下所示:
SELECT * FROM (
SELECT
ROW_NUMBER() OVER(PARTITION BY rf2.linkID ORDER BY rf2.testDate DESC) AS rn
,rf2.*, rs.*
FROM dbo.Unit rs
FULL OUTER JOIN dbo.TestingData rf ON ( rs.SN = rf.SN )
FULL OUTER JOIN dbo.Link rf1 ON ( rf.SN = rf1.SN)
FULL OUTER JOIN dbo.Tests rf2 ON ( rf1.linkID = rf2.linkID )
WHERE rf2.Testname = 'AD1' -- You should use `Testname` instead of `testType`
) T
WHERE rn = 1
ORDER BY SN ASC;
<强>输出:强>
rn LinkID testdate Testname record_ID SN Data1
1 1 2015-10-05 22:22:00.000 AD1 1 123 123 info