您好,并提前感谢您的时间。
我必须解决这个具体问题。 我有下面的邮票表
idStamp idCustomer uptoW uptoD price
----------- ----------- ----------- ----------- -----------
218 4 2200 690 205
218 4 1700 660 155
我需要找到符合4个条件的单行(如果存在): - idStamp - idCustomer - uptoW - uptoD
我用过
SELECT Distinct(UptoW) FROM [mytable]
WHERE uptoW=(SELECT MIN(uptoW)
FROM [mytable]
WHERE uptoW >= 1600-1 AND idStamp = 218 AND idCustomer = 4)
它适用于3个标准 - idStamp - idCustomer - uptoW
但我无法弄清楚如何实施第四个匹配标准。
总结
使用以下参数(idStamp = 218,idCustomer = 4,宽度= 1600,深度= 640)
我希望找到价格为155的行
...但是...
使用param(idStamp = 218,idCustomer = 4,Width = 1600,Depth = 670)
我希望找到价格为205的行
如果没有办法满足所有标准,我希望没有行。
- 编辑2013.12.13 -
idStamp idCustomer UptoW UptoD price
----------- ----------- ----------- ----------- -----------
218 4 220 69 155
218 4 170 100 205
218 4 230 100 400
218 4 180 90 345
218 4 180 89 34
218 4 179 90 32
218 4 179 89 2343
DECLARE @p_idStamp INT = 218
,@p_idCustomer INT = 4
,@UptoW INT = 160
,@UptoD INT = 89
,@UptoWmin int
,@UptoDmin int;
SELECT @UptoWmin = MIN(UptoW) FROM mytable<br>
WHERE UptoW =(SELECT MIN(UptoW) FROM mytable<br>
WHERE UptoW >= @UptoW-1 AND idStamp = 218 AND idCustomer = 4)<br>
SELECT @UptoDmin = MIN(UptoD) FROM mytable<br>
WHERE UptoD =(SELECT MIN(UptoD) FROM mytable<br>
WHERE UptoD >= @UptoD-1 AND idStamp = 218 AND idCustomer = 4)<br>
SELECT TOP(1) * FROM mytable<br>
WHERE UptoW >= @UptoWmin AND UptoD >= @UptoDmin<br>
ORDER BY UptoW, UptoD<br>
SELECT TOP(1) * FROM mytable<br>
WHERE UptoW >= @UptoWmin AND UptoD >= @UptoDmin<br>
ORDER BY UptoD, UptoW<br>
我可能找到了解决方案 如您所见,我首先搜索表中的确切最小值 然后我编写一个满足两个参数的查询。 我重复查询颠倒order by子句,因为结果可能不同。
让我知道是否可以采用更好的解决方案。
答案 0 :(得分:1)
我相信一种做你想要的方法是按超过区域排序结果,然后取第一行。
类似的东西:
-- Test schema, based on S Koppenol answer:
CREATE TABLE stamps (
[idStamp] INT,
[idCustomer] INT,
[uptoW] INT,
[uptoD] INT,
[price] MONEY
)
INSERT INTO stamps (
[idStamp], [idCustomer], [uptoW], [uptoD], [price]
) VALUES
(218, 4, 2200, 690, 205.0),
(218, 4, 1700, 660, 155.0)
GO
-- Procedure to find the desired row:
CREATE PROCEDURE GetRow(
@idStamp INT,
@idCustomer INT,
@uptoW INT,
@uptoD INT
) AS
BEGIN
SELECT TOP 1
T.idStamp,
T.idCustomer,
T.uptoW,
T.uptoD,
(T.uptoW * T.uptoD - @uptoW * @uptoD) AS DELTA_AREA
FROM
stamps T
WHERE
T.uptoW >= @uptoW + 1
AND T.uptoD >= @uptoD + 1
AND idStamp = @idStamp
AND idCustomer = @idCustomer
ORDER BY
DELTA_AREA
END
GO
-- Testing
EXEC GetRow 218, 4, 1600, 640;
EXEC GetRow 218, 4, 1700, 640;
EXEC GetRow 218, 4, 1600, 660;
EXEC GetRow 218, 4, 2200, 660;
测试结果:
idStamp idCustomer uptoW uptoD DELTA_AREA
----------- ----------- ----------- ----------- -----------
218 4 1700 660 98000
(1 row(s) affected)
idStamp idCustomer uptoW uptoD DELTA_AREA
----------- ----------- ----------- ----------- -----------
218 4 2200 690 430000
(1 row(s) affected)
idStamp idCustomer uptoW uptoD DELTA_AREA
----------- ----------- ----------- ----------- -----------
218 4 2200 690 462000
(1 row(s) affected)
idStamp idCustomer uptoW uptoD DELTA_AREA
----------- ----------- ----------- ----------- -----------
(0 row(s) affected)
这样你肯定会得到一条不仅在要求的限制范围内,而且还有最接近的记录。
答案 1 :(得分:0)
您可以将uptoD >= DESIRED_VALUE
添加到验证中。
例如:
SELECT Distinct(UptoW) FROM [stamps]
WHERE uptoW=(SELECT MIN(uptoW)
FROM [stamps]
WHERE uptoW >= 1600-1 AND uptoD >= 640 AND idStamp = 218 AND idCustomer = 4);
这会给你:
UPTOW
1700
但你可以进一步简化并做:
SELECT MIN(uptoW) AS UPTOW
FROM [stamps]
WHERE uptoW >= 1600-1
AND uptoD >= 640
AND idStamp = 218
AND idCustomer = 4
答案 2 :(得分:0)
我并不完全确定所期望的最终结果,但我认为这将会很接近。这将为您提供符合所有条件的最低 uptoW (如果有)的记录。
DECLARE @p_idStamp INT = 218
,@p_idCustomer INT = 4
,@p_uptoW INT = 1600
,@p_uptoD INT = 640;
SELECT TOP 1 *
FROM mytable
WHERE idStamp = @p_idStamp
AND idCustomer = @p_idCustomer
AND uptoW > @p_uptoW
AND uptoD > @p_uptoD
ORDER BY uptoW ASC;