选择要在 SQL 视图中使用的副本
Choose which duplicate to take in a SQL view
我正在尝试为我解决一个 SQL 问题,基本上是从两个副本中选择另一个列中我想要的那个。
我有三列:代码、值和描述:
code | value | description
23 | 1 | hello
23 | 2 | goodbye
此处代码栏重复。但在我看来,我只想要具有最高值的行,所以第二行。
我尝试在值列上使用 MAX()
,但我不知道如何将它多次应用于 table 中的代码。
我也在网上找到这个:
SELECT l.*
FROM livre l
INNER JOIN (
SELECT categorie, MAX(date) AS maxDate
FROM livre
GROUP BY categorie
) groupel ON l.categorie = groupel.categorie AND l.date = groupel.maxDate
但是我不明白l的意思。
你能帮我解决这个问题吗?或者有更好的提取方法吗?
使用 row_number()
window 函数 select 正确的行。
declare @Livre table (Code int, [Value] int, [Description] varchar(12));
insert into @Livre (Code, [Value], [Description])
values (23,1,'Hello'),(23,2,'Goodbye');
with cte as (
select Code, [Value], [Description]
, row_number() over (partition by Code order by [Value] desc) rn
from @Livre
)
select Code, [Value], [Description]
from cte
where rn = 1;
Returns:
Code Value Description
23 2 Goodbye
在您在互联网上找到的那个脚本中,'l' 是给(原始)table 的别名。
然后将其连接到一个子查询,该子查询 returns 相同 table 的最大日期。子查询的结果类似于一个单独的 table,并被赋予别名 'groupel'.
通过使用 INNER JOIN 并选择 l.*,这 returns 来自原始 table 的所有记录,其中子查询将其标识为给定类别的最大日期。
对于您的例子 table,类似这样的东西是等价的:
SELECT orig.*
FROM Table orig
INNER JOIN (
SELECT code, MAX(Value) AS MaxValue
FROM Table
GROUP BY code
) MAX ON orig.code = MAX.code AND orig.value = MAX.MaxValue
还有另一种方法,不使用CTE
。您可以 JOIN
table 自身 -
CREATE TABLE Livre (
[Code] int,
[Value] int,
[Description] varchar(25)
)
INSERT INTO Livre ([Code], [Value], [Description]) VALUES (23,1,'Hello')
INSERT INTO Livre ([Code], [Value], [Description]) VALUES (23,2,'Goodbye')
SELECT l2.[Code], l2.[Value], l2.[Description]
FROM Livre l1
JOIN Livre l2
ON l2.code = l1.code
AND l2.[Value] > l1.[Value]
输出-
Code Value Description
23 2 Goodbye
我认为相关子查询是一种简单且通常高性能的解决方案:
select l.*
from livre l
where l.value = (select max(l2.value)
from livre l2
where l2.code = l.code
);
为了性能,您需要 livree(code, value)
上的索引。
SELECT *
FROM Livre l1
WHERE EXISTS(
SELECT MAX(Value)
FROM Livre l2
WHERE l1.Code = l2.Code
HAVING L1.Value = MAX(VALUE)
)
我正在尝试为我解决一个 SQL 问题,基本上是从两个副本中选择另一个列中我想要的那个。
我有三列:代码、值和描述:
code | value | description
23 | 1 | hello
23 | 2 | goodbye
此处代码栏重复。但在我看来,我只想要具有最高值的行,所以第二行。
我尝试在值列上使用 MAX()
,但我不知道如何将它多次应用于 table 中的代码。
我也在网上找到这个:
SELECT l.*
FROM livre l
INNER JOIN (
SELECT categorie, MAX(date) AS maxDate
FROM livre
GROUP BY categorie
) groupel ON l.categorie = groupel.categorie AND l.date = groupel.maxDate
但是我不明白l的意思。
你能帮我解决这个问题吗?或者有更好的提取方法吗?
使用 row_number()
window 函数 select 正确的行。
declare @Livre table (Code int, [Value] int, [Description] varchar(12));
insert into @Livre (Code, [Value], [Description])
values (23,1,'Hello'),(23,2,'Goodbye');
with cte as (
select Code, [Value], [Description]
, row_number() over (partition by Code order by [Value] desc) rn
from @Livre
)
select Code, [Value], [Description]
from cte
where rn = 1;
Returns:
Code Value Description
23 2 Goodbye
在您在互联网上找到的那个脚本中,'l' 是给(原始)table 的别名。 然后将其连接到一个子查询,该子查询 returns 相同 table 的最大日期。子查询的结果类似于一个单独的 table,并被赋予别名 'groupel'.
通过使用 INNER JOIN 并选择 l.*,这 returns 来自原始 table 的所有记录,其中子查询将其标识为给定类别的最大日期。
对于您的例子 table,类似这样的东西是等价的:
SELECT orig.*
FROM Table orig
INNER JOIN (
SELECT code, MAX(Value) AS MaxValue
FROM Table
GROUP BY code
) MAX ON orig.code = MAX.code AND orig.value = MAX.MaxValue
还有另一种方法,不使用CTE
。您可以 JOIN
table 自身 -
CREATE TABLE Livre (
[Code] int,
[Value] int,
[Description] varchar(25)
)
INSERT INTO Livre ([Code], [Value], [Description]) VALUES (23,1,'Hello')
INSERT INTO Livre ([Code], [Value], [Description]) VALUES (23,2,'Goodbye')
SELECT l2.[Code], l2.[Value], l2.[Description]
FROM Livre l1
JOIN Livre l2
ON l2.code = l1.code
AND l2.[Value] > l1.[Value]
输出-
Code Value Description
23 2 Goodbye
我认为相关子查询是一种简单且通常高性能的解决方案:
select l.*
from livre l
where l.value = (select max(l2.value)
from livre l2
where l2.code = l.code
);
为了性能,您需要 livree(code, value)
上的索引。
SELECT *
FROM Livre l1
WHERE EXISTS(
SELECT MAX(Value)
FROM Livre l2
WHERE l1.Code = l2.Code
HAVING L1.Value = MAX(VALUE)
)