为了清晰起见,我决定编辑此内容。
以下是我的数据表。
BLDGID,LEASID,STARTDT和BRK在表BRKP
中OCCPSTAT和SUITID位于另一个名为STATUS的表中
INCATT在另一个名为BILL的表中
BLDGID LEASID STARTDT BRK OCCPSTAT SUITID INCCAT
9999 100 8/5/2011 100000 C AZ847 AVD
9999 100 8/5/2013 200000 C AZ847 AVD
9999 100 8/5/2015 300000 C AZ847 AVD
9999 100 8/5/2017 400000 C AZ847 AVD
9999 250 12/1/2012 200000 C BK497 TIL
9999 250 12/1/2016 400000 C BK497 TIL
9999 250 12/7/2020 500000 C BK497 TIL
9999 250 1/31/2023 600000 C BK497 TIL
7000 987 2/19/2016 0 C JT127 MTU
7000 987 5/19/2020 10000 C JT127 MTU
7000 987 3/18/2021 20000 C JT127 MTU
7000 987 9/4/2023 30000 C JT127 MTU
我想要的是为每个套件ID拉一行(每个BLDGID大约有100个独特的SUITID)。
在该行中,我需要在我定义的日期之前将STARTDT设置为最高值。
如果我定义20220831(08/31/2022),在这种情况下它应该拉一行,即第2行。
如果我定义20160831(2016年8月31日),它应该只拉第1行。
我无法弄清楚如何让它只拉一行。我可以得到很多。
我一直在尝试STARTDT =(最大(STARTDT)<' 20160831')和其他变体。
我没有输入日期的问题,它会拉7/5/2022但是,当我输入我的约会时,它什么都没有。
再次编辑:我已尝试添加以下内容,但不会更改返回的记录数。
SUITID,STARTDT DESC
选择TOP 1 *来自SUITID,STARTDT
进一步编辑:示例是该表的前4行。扩展以显示我正在使用更大的桌子。
答案 0 :(得分:0)
不要在HAVING
子句上按日期过滤,而是尝试使用WHERE
之前的GROUP BY
子句进行过滤,如下所示:
...
WHERE ((SQLDATA.dbo.BRKP.STARTDT) < '20160831')
GROUP BY SQLDATA.dbo.BRKP.BLDGID,
SQLDATA.dbo.BRKP.LEASID,
SQLDATA.dbo.BRKP.STARTDT,
SQLDATA.dbo.BRKP.BRKPNT1,
SQLDATA.dbo.LEAS.OCCPSTAT,
SQLDATA.dbo.LEAS.SUITID,
SQLDATA.dbo.RTBILL.INCCAT
HAVING (
((SQLDATA.dbo.BRKP.BLDGID) & SPARM03)
AND ((SQLDATA.dbo.LEAS.OCCPSTAT) = 'c')
)
基本上,在分组之前,您只使用您感兴趣的内容对数据进行预过滤。
答案 1 :(得分:0)
我的猜测是你需要使用日期而不是字符串来处理你的HAVING子句中的不等式:
SELECT SQLDATA.dbo.BRKP.BLDGID AS 'BLDGID',
SQLDATA.dbo.BRKP.LEASID AS 'LEASID',
SQLDATA.dbo.BRKP.STARTDT AS 'STARTDT',
SQLDATA.dbo.BRKP.BRKPNT1 AS 'BRKPNT1',
SQLDATA.dbo.LEAS.OCCPSTAT AS 'OCCPSTAT',
SQLDATA.dbo.LEAS.SUITID AS 'SUITID',
SQLDATA.dbo.RTBILL.INCCAT AS 'INCCAT'
FROM SQLDATA.dbo.CMLEDG
INNER JOIN SQLDATA.dbo.LEAS ON SQLDATA.dbo.CMLEDG.BLDGID = SQLDATA.dbo.LEAS.BLDGID
AND SQLDATA.dbo.CMLEDG.LEASID = SQLDATA.dbo.LEAS.LEASID
INNER JOIN SQLDATA.dbo.RTBILL ON SQLDATA.dbo.CMLEDG.BLDGID = SQLDATA.dbo.RTBILL.BLDGID
AND SQLDATA.dbo.CMLEDG.LEASID = SQLDATA.dbo.RTBILL.LEASID
INNER JOIN SQLDATA.dbo.BRKP ON SQLDATA.dbo.CMLEDG.BLDGID = SQLDATA.dbo.BRKP.BLDGID
AND SQLDATA.dbo.CMLEDG.LEASID = SQLDATA.dbo.BRKP.LEASID
INNER JOIN SQLDATA.dbo.BRKP BRKP2 ON SQLDATA.dbo.CMLEDG.BLDGID = BRKP2.BLDGID
AND SQLDATA.dbo.CMLEDG.LEASID = BRKP2.LEASID SQLDATA.DBO.BRKP.STARTDT =
(
SELECT MAX(SQLDATA.DBO.BRKP.STARTDT)
FROM SQLDATA.DBO.BRKP
WHERE SQLDATA.DBO.LEAS.BLDGID = SQLDATA.DBO.BRKP.BLDGID
AND SQLDATA.DBO.LEAS.LEASID = SQLDATA.DBO.BRKP.LEASID
)
GROUP BY SQLDATA.dbo.BRKP.BLDGID,
SQLDATA.dbo.BRKP.LEASID,
SQLDATA.dbo.BRKP.STARTDT,
SQLDATA.dbo.BRKP.BRKPNT1,
SQLDATA.dbo.LEAS.OCCPSTAT,
SQLDATA.dbo.LEAS.SUITID,
SQLDATA.dbo.RTBILL.INCCAT
HAVING SQLDATA.dbo.BRKP.BLDGID & SPARM03
AND SQLDATA.dbo.BRKP.STARTDT < Convert(datetime, '2016-08-31' )
AND SQLDATA.dbo.LEAS.OCCPSTAT = 'c'
答案 2 :(得分:0)
目前还不清楚完全你需要什么。但是,显然您需要一个where
子句并简化GROUP BY
。因此,您的查询需要以下内容:
SELECT . . .,
MAX(SQLDATA.dbo.BRKP.STARTDT)
FROM . . .
WHERE SQLDATA.dbo.BRKP.STARTDT < '20160831'
GROUP BY SQLDATA.dbo.BRKP.BLDGID,
SQLDATA.dbo.BRKP.LEASID,
SQLDATA.dbo.BRKP.BRKPNT1,
SQLDATA.dbo.LEAS.OCCPSTAT,
SQLDATA.dbo.LEAS.SUITID,
SQLDATA.dbo.RTBILL.INCCAT
HAVING ( (SQLDATA.dbo.BRKP.STARTDT) < '20160831') AND
((SQLDATA.dbo.LEAS.OCCPSTAT) = 'c')
)
目前还不清楚是否有任何其他条件也应该移动WHERE
条款,但我猜是“是”。
答案 3 :(得分:0)
请原谅我没有通过并将这一切都挂到您的代码中,但我理解您正在寻找的是
SELECT TOP (1)
然后
WHERE myDate <= @theDateValue
非常重要
ORDER BY myDate DESC
一般来说,这是你可以在某事之前得到最后一条记录的方法。上述示例中的性能会受到“myDate”上是否存在索引的影响很大,因为如果是这样,引擎可以直接转到正确的页面,只需读取一些内容并提取所需的单个记录。
答案 4 :(得分:0)
经常当有人想要与&#34;最大日期&#34;相关的数据时最好的方法是使用ROW_NUMBER()OVER()
我认为这可能会产生你想要的东西:
SELECT
BLDGID
, LEASID
, STARTDT
, BRKPNT1
, OCCPSTAT
, SUITID
, INCCAT
FROM (
SELECT
br.BLDGID
, br.LEASID
, br.STARTDT
, br.BRKPNT1
, le.OCCPSTAT
, le.SUITID
, rb.INCCAT
, ROW_NUMBER() OVER(PARTITION BY br.BLDGID, br.LEASID, le.OCCPSTAT, le.SUITID, rb.INCCAT
ORDER BY br.STARTDT DESC) AS rowno
FROM SQLDATA.dbo.CMLEDG cm
INNER JOIN SQLDATA.dbo.LEAS le ON cm.BLDGID = le.BLDGID AND cm.LEASID = le.LEASID
INNER JOIN SQLDATA.dbo.RTBILL rb ON cm.BLDGID = rb.BLDGID AND cm.LEASID = rb.LEASID
INNER JOIN SQLDATA.dbo.BRKP br ON cm.BLDGID = br.BLDGID AND cm.LEASID = br.LEASID
WHERE br.STARTDT < '20160831'
AND le.OCCPSTAT = 'c'
) AS d
WHERE rowno = 1
在OVER()内为&#34;分区列出的列&#34;行为有点像你的&#34;组&#34;因为当值组合发生变化时,重新开始计数。所以,因为这也是使用降序&#34;顺序&#34;对于&#34;最新日期&#34;,您希望日期得到值1。如果还与where子句结合使用:&lt; 20160831&#39;
之前的最近日期我想提出几点补充说明: