【发布时间】:2011-01-11 19:05:03
【问题描述】:
我需要从下表中的每组重复记录中提取第一行。 我需要在视图中使用这个查询
请不要使用临时表,因为我已经通过添加标识列和 min 函数和 group by 来完成它。我需要没有临时表或表变量的解决方案
这只是示例数据。原始表中有 1000 条记录,我只需要前 1000 条的结果,所以我不能使用 distinct
我使用的是 SQL Server 2005
【问题讨论】:
标签: sql sql-server-2005 tsql
我需要从下表中的每组重复记录中提取第一行。 我需要在视图中使用这个查询
请不要使用临时表,因为我已经通过添加标识列和 min 函数和 group by 来完成它。我需要没有临时表或表变量的解决方案
这只是示例数据。原始表中有 1000 条记录,我只需要前 1000 条的结果,所以我不能使用 distinct
我使用的是 SQL Server 2005
【问题讨论】:
标签: sql sql-server-2005 tsql
查找已订购 1 次或多次的所有产品...(重复记录的种类)
SELECT DISTINCT * from [order_items] where productid in
(SELECT productid
FROM [order_items]
group by productid
having COUNT(*)>0)
order by productid
要选择最后插入的那些...
SELECT DISTINCT productid, MAX(id) OVER (PARTITION BY productid) AS LastRowId from [order_items] where productid in
(SELECT productid
FROM [order_items]
group by productid
having COUNT(*)>0)
order by productid
【讨论】:
答案具体取决于您所说的“前 1000 条不同”记录是什么意思。
如果您的意思是要返回最多 1000 条不同的记录,而不管表中有多少重复项,请这样写:
SELECT DISTINCT TOP 1000 id, uname, tel
FROM Users
ORDER BY <sort_columns>
如果您只想搜索表中的前 1000 行,并且可能返回少于 1000 个不同的行,那么您可以使用子查询或 CTE 编写它,如下所示:
SELECT DISTINCT *
FROM
(
SELECT TOP 1000 id, uname, tel
FROM Users
ORDER BY <sort_columns>
) u
如果您不关心返回哪些记录,ORDER BY 当然是可选的。
【讨论】:
有时您可以像这样使用 CROSS APPLY 运算符:
select distinct result.* from data d
cross apply (select top 1 * from data where data.Id = d.Id) result
在这个查询中,我只需要选择在我的数据中自然发生的许多重复项中的第一个。它适用于 SQL Server 2005+ 数据库。
【讨论】:
select distinct result.* 和result,这是怎么回事
result。此虚拟表通过 Id 列与“核心”表数据连接。另请注意,我还为data 表提供了一个新别名,名为d,因此我可以在交叉应用中定义的“虚拟表”中引用它。最后,我只想返回这个新的虚拟表,名为result。我需要要求 distinct 因为数据集通常有很多重复。
您可以尝试以下方法:
创建一个视图,该视图仅选择原始表中的所有列,但添加一个额外的数字列,该列的值随每条记录\行而增加。您可能需要将此列设置为非整数列(例如,为每条记录增加 1.00 以在 RANK() SQL 语句中使用它)。
还添加另一列(例如“RecordRank”)以包含所有列的计算排名值,使用 RANK() OVER SQL 子句为该列创建值 - 请参阅下面的参考资料。 RANK 语句允许您对记录进行分区,然后根据 order by 列中的值对每个分区记录进行排序(使用从步骤 1 开始增加值的 Column 作为您的 order by)。您在分区子句中使用具有相同数据的列,因此所有这些相似的重复项都被分区或分组在一起,然后按额外列中的值排序(从第 1 步开始按列排序)。
3、上面的视图创建成功后,再写一个视图只选择'RecordRank' = 1的记录
这应该只从重复项或分区中选择每条记录之一。
希望这会有所帮助 - malcom sankoh
【讨论】:
SELECT DISTINCT 没有帮助吗?我想它会返回你想要的结果。
【讨论】:
使用 DISTINCT 应该可以做到:
SELECT DISTINCT id, uname, tel
FROM YourTable
虽然您确实可以在该表上使用主键,但这是一种唯一标识每条记录的方法。我会考虑在桌子上贴一个 IDENTITY 列
【讨论】:
您最好的办法是修复数据库设计并将身份列添加到表中。为什么你的桌子一开始就没有桌子?尤其是有重复记录的!显然,数据库本身需要重新设计。
为什么你必须在视图中显示这个,为什么你的临时表解决方案不是一个有效的解决方案?对于一个完美的数据库来说,视图通常不是一件好事。
【讨论】:
这里有两种解决方案,我使用的是Oracle SQL server:
1) 使用 over 子句:
with org_table as
(select 1 id, 'Ali' uname
from dual
union
select 1, 'June'
from dual
union
select 2, 'Jame'
from dual
union
select 2, 'July' from dual)
select id, uname
from (select a.id,
a.uname,
ROW_NUMBER() OVER(PARTITION BY a.id ORDER BY a.id) AS freq
from org_table a)
where freq = 1
2) 使用子查询:
with org_table as
(select 1 id, 'Ali' uname
from dual
union
select 1, 'June'
from dual
union
select 2, 'Jame'
from dual
union
select 2, 'July' from dual)
select a.id,
(select b.uname
from org_table b
where b.id = a.id
and rownum = 1)
from (select distinct id from org_table) a
【讨论】:
SELECT TOP 1000 MAX(tel) FROM TableName WHERE Id IN
(
SELECT Id FROM TableName
GROUP BY Id
HAVING COUNT(*) > 1
)
GROUP BY Id
【讨论】: