我需要获取最大值和最小值,但我还需要在同一行上获得这些最大值或最小值的行ID。
SELECT MIN([Value]), MAX([Value]), id
FROM [AnalystEstimates].[dbo].[AnalystEstimateValues]
GROUP BY indicatorid
答案 0 :(得分:3)
目前还不清楚你的问题是什么。你真的想要GROUP BY indicatorid吗?如果没有,那么它很简单,你已经有很多答案。但是如果你确实想要GROUP BY那么它就更难了,而且没有人能够把它弄得很好。我还假设你只需要每个indicatorid一行,如果有重复的行具有相同的max / min,那么最好只选择其中一行而不是返回两者。
这是我尝试使用CTE(需要SQL Server 2005或更新版本):
WITH
RowNumbers AS (
SELECT ROW_NUMBER() OVER (ORDER BY indicatorid, value) AS RowNumber, *
FROM [AnalystEstimates].[dbo].[AnalystEstimateValues]),
MinRowNumbers AS (
SELECT indicatorid, MIN(RowNumber) AS RowNumber FROM RowNumbers GROUP BY indicatorid),
MaxRowNumbers AS (
SELECT indicatorid, MAX(RowNumber) AS RowNumber FROM RowNumbers GROUP BY indicatorid)
SELECT
MinRowNumbers.indicatorid,
RN1.Value AS MinValue,
RN1.ID AS MinValueId,
RN2.Value AS MaxValue,
RN2.ID AS MaxValueId
FROM MinRowNumbers
JOIN MaxRowNumbers ON MinRowNumbers.indicatorid = MaxRowNumbers.indicatorid
JOIN RowNumbers RN1 ON MinRowNumbers.RowNumber = RN1.RowNumber
JOIN RowNumbers RN2 ON MaxRowNumbers.RowNumber = RN2.RowNumber
以下是我用来测试它的一些数据:
CREATE TABLE AnalystEstimateValues (ID int, indicatorid int, Value int);
INSERT INTO AnalystEstimateValues (ID, indicatorid , Value) VALUES
(1, 1, 4),
(2, 1, 4),
(3, 2, 6),
(4, 1, 2),
(5, 2, 2),
(6, 2, 5),
(7, 3, 0);
这是我得到的输出:
indicatorid MinValue MinValueId MaxValue MaxValueId
1 2 4 4 2
2 2 5 6 3
3 0 7 0 7
如果这不是您想要的,请您尝试改进您的问题,告诉我们您的需求吗?
更新:这是基于Craig Young答案的替代解决方案,但使用连接而不是子选择:
WITH
UniqueIds AS (
SELECT IndicatorId, Value, MIN(id) AS Id
FROM AnalystEstimateValues
GROUP BY IndicatorId, Value)
SELECT
lims.IndicatorId,
MinValue,
T1.Id AS MinValueId,
MaxValue,
T2.Id AS MaxValueId
FROM (
SELECT
IndicatorId,
MIN(Value) as MinValue,
MAX(Value) as MaxValue
FROM AnalystEstimateValues
GROUP BY IndicatorId) lims
JOIN UniqueIds T1 ON lims.IndicatorId = T1.IndicatorId AND lims.MinValue = T1.Value
JOIN UniqueIds T2 ON lims.IndicatorId = T2.IndicatorId AND lims.MaxValue = T2.Value
虽然我没有运行性能测试来验证这一点,但它比我的第一个版本更清晰,也可能更快。
答案 1 :(得分:1)
如果Min = Max,您将获得相同的ID(可能存在最小值和最大值绑定)
如果没有,则每个最小/最大值都有ID 。
基本上你可以有2行或4列。
SELECT
Mn.ID, foo.MinVal,
Mx.ID, foo.MaxVal
FROM
(
SELECT
MIN([Value]) AS MinVal,
MAX([Value]) AS MaxVal,
indicatorid
FROM
[AnalystEstimates].[dbo].[AnalystEstimateValues]
GROUP BY
indicatorid
) foo
JOIN
[AnalystEstimates].[dbo].[AnalystEstimateValues] Mn ON
foo.MinVal = Mn.[Value] AND foo.indicatorid = Mn.indicatorid
JOIN
[AnalystEstimates].[dbo].[AnalystEstimateValues] Mx ON
foo.MaxVal = Mx.[Value] AND foo.indicatorid = Mx.indicatorid
编辑:
除非定义为WITH TIES
,否则TOP解决方案不会为您提供已绑定MIN / MAX值的行答案 2 :(得分:1)
重要问题
Mark Byers的样本数据显示了您需要考虑的场景:
那么应该显示两个id中的哪一个?
我认为它足以显示最低的id。以下查询应该是最有效的,并且将受益于(indicatorid,Value)上的索引。
SELECT lims.*,
(
SELECT MIN(id)
FROM AnalystEstimateValues m
WHERE m.IndicatorId = lims.IndicatorId
AND m.Value = lims.MinValue
) AS MinId,
(
SELECT MIN(id)
FROM AnalystEstimateValues m
WHERE m.IndicatorId = lims.IndicatorId
AND m.Value = lims.MaxValue
) AS MaxId
FROM (
SELECT IndicatorId,
MIN(Value) as MinValue,
MAX(Value) as MaxValue
FROM AnalystEstimateValues
GROUP BY IndicatorId
) lims
答案 3 :(得分:0)
当您按ID分组时,您的查询将返回每个ID的最大/最小值。试试这样的事情
SELECT tblFoo.ID, tblFoo.Value
FROM tblFoo
WHERE (((tblFoo.Value)=(SELECT MAX( [tblFoo]![Value] ) FROM tblFoo)))
OR (((tblFoo.Value)=(SELECT MIN( [tblFoo]![Value] ) FROM tblFoo)));
答案 4 :(得分:0)
SELECT TOP 1
ID,
'min' as type,
value
FROM
AnalystEstimateValues
WHERE
value = (select min(value) from AnalystEstimateValues)
UNION
SELECT TOP 1
ID,
'max' as type,
value
FROM
AnalystEstimateValues
WHERE
value = (select max(value ) from AnalystEstimateValues)
答案 5 :(得分:0)
这可能会这样做,虽然我没有mssql所以我无法测试它。特别是方括号可能需要调整。除此之外,它应该是相当标准的SQL并做你想要的。
它获得由indicatorid分组的所有min(id / value)和max(id / value)。 在同一行。
SELECT mint.indicatorid, mint.min_id, mint.min_value, maxt.max_id, maxt.max_value
FROM (
SELECT indicatorid, id as min_id, MIN([Value]) AS min_value
FROM [AnalystEstimates].[dbo].[AnalystEstimateValues]
HAVING [Value] = min_value
GROUP BY indicatorid
) mint JOIN (
SELECT indicatorid, id as max_id, MAX([Value]) AS max_value
FROM [AnalystEstimates].[dbo].[AnalystEstimateValues]
HAVING [Value] = max_value
GROUP BY indicatorid
) maxt ON mint.indicatorid = maxt.indicatorid