这是示例表
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CypherCollectionViewCell", for: indexPath as IndexPath) as! CypherCollectionViewCell
cell.tickButton.addTarget(self, action: #selector(tickButtonClicked(sender:)), for: .touchUpInside)
return cell
}
@objc func tickButtonClicked( sender: UIButton) {
var convertedPoint : CGPoint = sender.convert(CGPoint.zero, to: self. collectionView)
var indexPath = self. collectionView.indexPathForItemAtPoint(convertedPoint)
let cell = self. collectionView.cellForItemAtIndexPath(indexPath) as! CypherCollectionViewCell
if sender.isSelected {
sender.isSelected = false
// To change the UIView border color
cell.view.borderColor = UIColor.blue()
} else {
sender.isSelected = true
// To change the UIView border color
cell.view.borderColor = UIColor.red()
}
}
这是选择结果查询,其中tglValid位于2个日期之间
SELECT NoPolisi, ComLocID, Jenis, TglValid, rn
FROM (
SELECT NoPolisi, ComLocID, Jenis, TglValid, NoPolisiBaru,
ROW_NUMBER() OVER (PARTITION BY NoPolisi ORDER BY TglValid) rn
FROM MstData.dbo.Ms_UbahBentukArmada
) A
WHERE NoPolisi = 'BK 8819 CF'
上面的查询结果是
我的问题是,我能得到所选结果在上方还是下方有额外的一行,因此结果包含rn = 5行或rn = 2行?
编辑: 在它使用的@gotqn答案中
DECLARE
@DateFrom smalldatetime = '20170101',
@DateTo smalldatetime = '20171201'
SELECT NoPolisi, ComLocID, Jenis, TglValid, rn
FROM (
SELECT NoPolisi, ComLocID, Jenis, TglValid, NoPolisiBaru,
ROW_NUMBER() OVER (PARTITION BY NoPolisi ORDER BY TglValid) rn
FROM MstData.dbo.Ms_UbahBentukArmada
) A
WHERE NoPolisi = 'BK 8819 CF'
AND TglValid BETWEEN @DateFrom AND @DateTo
但是如果日期范围在中间,如上面的代码 它必须返回第2行:
DECLARE @DataSource TABLE
(
[id] INT
,[date] DATETIME2(0)
);
INSERT INTO @DataSource ([id], [date])
VALUES (100, '2000-01-01')
,(110, '2016-03-01')
,(120, '2017-06-06')
,(130, '2017-07-01')
,(140, '2018-01-01');
DECLARE
@DateFrom smalldatetime = '20170401',
@DateTo smalldatetime = '20170430';
WITH DataSource AS
(
SELECT *
,ROW_NUMBER() OVER (ORDER BY [date]) AS [rn]
,IIF
(
[date] BETWEEN @DateFrom AND @DateTo
OR
LAG([date]) OVER(ORDER BY [date]) BETWEEN @DateFrom AND @DateTo
,1
,0
) AS [in_interval]
FROM @DataSource
)
SELECT *
FROM DataSource
-- WHERE [in_interval] = 1;
感谢帮助。
答案 0 :(得分:2)
因此,您需要具备以下条件:
rn
小于最小输出数据rn
rn
比最大的输出数据rn
当rn
在SELECT
phase中计算时,为了使用它,我们需要具体化结果。然后,使用UNION ALL
使用WHERE [rn] = (SELECT MIN(rn) - 1 FROM data)
或WHERE [rn] = (SELECT max(rn) + 1 FROM data)
添加所需的记录。
下面,我正在使用另一种使用self join
的方法。因此,此查询:
DECLARE @DataSource TABLE
(
[id] INT
,[date] DATETIME2(0)
);
INSERT INTO @DataSource ([id], [date])
VALUES (100, '2000-01-01')
,(110, '2016-03-01')
,(120, '2017-06-06')
,(130, '2017-07-01')
,(140, '2018-01-01');
DECLARE
@DateFrom smalldatetime = '20170101',
@DateTo smalldatetime = '20171201';
WITH DataSource AS
(
SELECT *
,ROW_NUMBER() OVER (ORDER BY [date]) AS [rn]
,CASE WHEN [date] BETWEEN @DateFrom AND @DateTo THEN 1 ELSE 0 END AS [in_interval]
FROM @DataSource
)
SELECT *
FROM DataSource DS1
LEFT JOIN DataSource DS2
ON DS1.[rn] = DS2.[rn] - 1;
因此,您需要添加WHERE DS1.[in_interval] = 1 OR DS2.[in_interval] = 1
。为了获得下一行,请从此更改ON
子句:
ON DS1.[rn] = DS2.[rn] - 1
对此:
ON DS1.[rn] = DS2.[rn] + 1
或添加其他自连接以获取两行。
对于SQL Server 2012+
,您可以使用LEAD
和LAG
函数来计算是否应包含行:
WITH DataSource AS
(
SELECT *
,ROW_NUMBER() OVER (ORDER BY [date]) AS [rn]
,IIF
(
[date] BETWEEN @DateFrom AND @DateTo
OR
LAG([date]) OVER(ORDER BY [date]) BETWEEN @DateFrom AND @DateTo
,1
,0
) AS [in_interval]
FROM @DataSource
)
SELECT *
FROM DataSource
-- WHERE [in_interval] = 1;
我们需要添加其他列以计算范围内的行数。如果行中没有行,则使用UNION ALL
提取一行:
WITH DataSource AS
(
SELECT *
,ROW_NUMBER() OVER (ORDER BY [date]) AS [rn]
,IIF
(
[date] BETWEEN @DateFrom AND @DateTo
OR
LAG([date]) OVER(ORDER BY [date]) BETWEEN @DateFrom AND @DateTo
,1
,0
) AS [in_interval]
,SUM(IIF( [date] BETWEEN @DateFrom AND @DateTo, 1, 0)) OVER() valid_dates
FROM @DataSource
)
SELECT *
FROM DataSource
WHERE [in_interval] = 1
UNION ALL
SELECT *
FROM
(
SELECT TOP 1 *
FROM DataSource
WHERE [date] < @DateFrom
AND [valid_dates] = 0
ORDER BY [rn] DESC
) DS
答案 1 :(得分:1)
感谢所有答案。 我想要的结果就是这样
DECLARE @DataSource TABLE
(
[id] INT
,[date] DATETIME2(0)
);
INSERT INTO @DataSource ([id], [date])
VALUES (100, '2000-01-01')
,(100, '2016-03-01')
,(100, '2017-06-06')
,(100, '2017-07-01')
,(100, '2018-01-01');
DECLARE
@DateFrom smalldatetime = '20170401',
@DateTo smalldatetime = '20180101';
SELECT * FROM @DataSource WHEre date between @DateFrom AND @DateTo
UNION ALL
SELECT id, max(date) date FROM @DataSource where date < @DateFrom group by id
感谢@gotqn给予帮助的时间