SQL 服务器:Select WHERE 字段不能包含 VALUE
SQL Server : Select WHERE Field may not contain VALUE
我知道标题含糊不清,但我不确定如何措辞。
我有一个简单的table(见下图)。
我需要编写一个 SQL 语句来检索代表每个 [UNIT_ID]
和 [ISACTIVE]
的单个记录,其中 [ISACTIVE]
是该特定 [=13] 的最大值=].
理想情况下,结果应如下所示(注意 UNIT_ID=2
没有 ISACTIVE=1
):
做一个简单的 [ISACTIVE] > 0
是 不是 我要找的东西,因为那样 UNIT_ID=2
永远不会出现在记录中。
这是我尝试过的(失败):
SELECT
[ID], [UNIT_ID], [REV], [ISACTIVE], [DATE_ENTERED]
FROM
TestTable
WHERE
([ISACTIVE] = (SELECT MAX([ISACTIVE])
FROM TestTable
WHERE ([UNIT_ID] = [UNIT_ID])));
-- This code only reveals two records (its missing record #4)
如有任何帮助,我们将不胜感激!
与NOT EXISTS
:
SELECT t.[ID], t.[UNIT_ID], t.[REV], t.[ISACTIVE], t.[DATE_ENTERED]
FROM TestTable AS t
WHERE NOT EXISTS (
SELECT 1 FROM TestTable
WHERE [UNIT_ID] = t.[UNIT_ID] AND [ISACTIVE] > t.[ISACTIVE]
)
或 ROW_NUMBER()
:
SELECT t.[ID], t.[UNIT_ID], t.[REV], t.[ISACTIVE], t.[DATE_ENTERED]
FROM (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY [UNIT_ID] ORDER BY [ISACTIVE] DESC) AS rn
FROM TestTable
) AS t
WHERE t.rn = 1
您的代码的问题是子查询没有为 TestTable
使用别名。应该是
SELECT
[ID], [UNIT_ID], [REV], [ISACTIVE], [DATE_ENTERED]
FROM TestTable ta
WHERE (
[ISACTIVE]=
(SELECT MAX(t.[ISACTIVE]) FROM TestTable t WHERE (t.[UNIT_ID]=ta.[UNIT_ID])));
正如@forpas 所说,我认为最好的选择是:
SELECT t.[ID], t.[UNIT_ID], t.[REV], t.[ISACTIVE], t.[DATE_ENTERED]
FROM (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY [UNIT_ID] ORDER BY [UNIT_ID, ISACTIVE] DESC) AS row_number
FROM TestTable
) AS t
WHERE t.row_number = 1
唯一的区别是 order by
子句,它必须包含那些列 UNIT_ID, ISACTIVE
.
希望对您有所帮助。
我知道标题含糊不清,但我不确定如何措辞。
我有一个简单的table(见下图)。
我需要编写一个 SQL 语句来检索代表每个 [UNIT_ID]
和 [ISACTIVE]
的单个记录,其中 [ISACTIVE]
是该特定 [=13] 的最大值=].
理想情况下,结果应如下所示(注意 UNIT_ID=2
没有 ISACTIVE=1
):
做一个简单的 [ISACTIVE] > 0
是 不是 我要找的东西,因为那样 UNIT_ID=2
永远不会出现在记录中。
这是我尝试过的(失败):
SELECT
[ID], [UNIT_ID], [REV], [ISACTIVE], [DATE_ENTERED]
FROM
TestTable
WHERE
([ISACTIVE] = (SELECT MAX([ISACTIVE])
FROM TestTable
WHERE ([UNIT_ID] = [UNIT_ID])));
-- This code only reveals two records (its missing record #4)
如有任何帮助,我们将不胜感激!
与NOT EXISTS
:
SELECT t.[ID], t.[UNIT_ID], t.[REV], t.[ISACTIVE], t.[DATE_ENTERED]
FROM TestTable AS t
WHERE NOT EXISTS (
SELECT 1 FROM TestTable
WHERE [UNIT_ID] = t.[UNIT_ID] AND [ISACTIVE] > t.[ISACTIVE]
)
或 ROW_NUMBER()
:
SELECT t.[ID], t.[UNIT_ID], t.[REV], t.[ISACTIVE], t.[DATE_ENTERED]
FROM (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY [UNIT_ID] ORDER BY [ISACTIVE] DESC) AS rn
FROM TestTable
) AS t
WHERE t.rn = 1
您的代码的问题是子查询没有为 TestTable
使用别名。应该是
SELECT
[ID], [UNIT_ID], [REV], [ISACTIVE], [DATE_ENTERED]
FROM TestTable ta
WHERE (
[ISACTIVE]=
(SELECT MAX(t.[ISACTIVE]) FROM TestTable t WHERE (t.[UNIT_ID]=ta.[UNIT_ID])));
正如@forpas 所说,我认为最好的选择是:
SELECT t.[ID], t.[UNIT_ID], t.[REV], t.[ISACTIVE], t.[DATE_ENTERED]
FROM (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY [UNIT_ID] ORDER BY [UNIT_ID, ISACTIVE] DESC) AS row_number
FROM TestTable
) AS t
WHERE t.row_number = 1
唯一的区别是 order by
子句,它必须包含那些列 UNIT_ID, ISACTIVE
.
希望对您有所帮助。