如何在普通SQL中只选择一个元素

如何在普通SQL中只选择一个元素,sql,sql-server,oracle,Sql,Sql Server,Oracle,我见过其他类似的问题,但我还没有找到一个能真正帮助我的。我有一个表,定义如下: CREATE TABLE "DOWNLOAD_HISTORY" ( "ID" NUMBER GENERATED BY DEFAULT AS IDENTITY MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 344 CACHE 20 NOORDER NOCYCLE

我见过其他类似的问题,但我还没有找到一个能真正帮助我的。我有一个表,定义如下:

CREATE TABLE "DOWNLOAD_HISTORY" 
   (    "ID" NUMBER GENERATED BY DEFAULT AS IDENTITY MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 344 CACHE 20 NOORDER  NOCYCLE  NOKEEP  NOSCALE  NOT NULL ENABLE, 
    "IDUSER" NUMBER NOT NULL ENABLE, 
    "IDFORNITORE" NUMBER NOT NULL ENABLE, 
    "IDRFX" NUMBER NOT NULL ENABLE, 
    "DOCNUM" NUMBER NOT NULL ENABLE, 
    "DOWNLOAD_TIMESTAMP" TIMESTAMP (6) NOT NULL ENABLE
   ) ;
此DDL来自OracleDB12数据库。 下面是一些示例数据 我想完成的是:如果已经有一行具有相同的元组IDRFX,DOCNUM,则不将其包含在SELECT语句中。因此,元组384,1应该只出现一次

到目前为止,我所做的是:考虑到这个查询甚至可以从MSSQL数据库执行,我尝试用纯SQL编写这两个查询

SELECT * 
FROM DOWNLOAD_HISTORY dh 
WHERE dh.IDRFX = 384 AND ID IN (SELECT ID FROM DOWNLOAD_HISTORY dh2 WHERE dh.DOCNUM <> dh2.DOCNUM AND dh.IDRFX <> dh2.IDRFX )



SELECT t1.*
FROM DOWNLOAD_HISTORY t1
WHERE NOT EXISTS (SELECT * from DOWNLOAD_HISTORY t2
                  where t2.DOCNUM = t1.DOCNUM 
                    and t2.IDRFX = t1.IDRFX)

但他们没有一个人真的能把我带到任何地方。如果可能的话,我想问一下我在哪里犯了这个错误,以及如何纠正它。

我想你的回答不起作用,因为下载时间戳是唯一的。只有列IDUSER、IDFORNITORE、IDRFX和IDRFX似乎多次包含相同的元组

因此,您可以对确实应该是不同的列执行SELECT DISTINCT,这样就没有ID或下载\u时间戳,或者在WHERE Not exist中调整superquery,并将SELECT*更改为SELECT,然后只选择希望具有唯一元组的列

所以这对我来说是最简单的解决方案

SELECT DISTINCT
IDUSER, 
IDFORNITORE, 
IDRFX, 
IDRFX
FROM Database

我猜你的答案不起作用,因为下载时间戳是唯一的。只有列IDUSER、IDFORNITORE、IDRFX和IDRFX似乎多次包含相同的元组

因此,您可以对确实应该是不同的列执行SELECT DISTINCT,这样就没有ID或下载\u时间戳,或者在WHERE Not exist中调整superquery,并将SELECT*更改为SELECT,然后只选择希望具有唯一元组的列

所以这对我来说是最简单的解决方案

SELECT DISTINCT
IDUSER, 
IDFORNITORE, 
IDRFX, 
IDRFX
FROM Database
您可以按如下方式使用行数分析函数:

SELECT * FROM
(SELECT t1.*, row_number() over (partition by t1.DOCNUM, t1.IDRFX order by 1) as rn
FROM DOWNLOAD_HISTORY t1)
WHERE RN = 1;
SELECT t1.*
FROM DOWNLOAD_HISTORY t1
WHERE NOT EXISTS (SELECT * from DOWNLOAD_HISTORY t2
                  where t2.DOCNUM = t1.DOCNUM 
                    and t2.IDRFX = t1.IDRFX
                    and t2.ID > t1.ID); -- add only this condition in your query
也可以按如下方式使用NOT EXISTS查询:

SELECT * FROM
(SELECT t1.*, row_number() over (partition by t1.DOCNUM, t1.IDRFX order by 1) as rn
FROM DOWNLOAD_HISTORY t1)
WHERE RN = 1;
SELECT t1.*
FROM DOWNLOAD_HISTORY t1
WHERE NOT EXISTS (SELECT * from DOWNLOAD_HISTORY t2
                  where t2.DOCNUM = t1.DOCNUM 
                    and t2.IDRFX = t1.IDRFX
                    and t2.ID > t1.ID); -- add only this condition in your query
您可以按如下方式使用行数分析函数:

SELECT * FROM
(SELECT t1.*, row_number() over (partition by t1.DOCNUM, t1.IDRFX order by 1) as rn
FROM DOWNLOAD_HISTORY t1)
WHERE RN = 1;
SELECT t1.*
FROM DOWNLOAD_HISTORY t1
WHERE NOT EXISTS (SELECT * from DOWNLOAD_HISTORY t2
                  where t2.DOCNUM = t1.DOCNUM 
                    and t2.IDRFX = t1.IDRFX
                    and t2.ID > t1.ID); -- add only this condition in your query
也可以按如下方式使用NOT EXISTS查询:

SELECT * FROM
(SELECT t1.*, row_number() over (partition by t1.DOCNUM, t1.IDRFX order by 1) as rn
FROM DOWNLOAD_HISTORY t1)
WHERE RN = 1;
SELECT t1.*
FROM DOWNLOAD_HISTORY t1
WHERE NOT EXISTS (SELECT * from DOWNLOAD_HISTORY t2
                  where t2.DOCNUM = t1.DOCNUM 
                    and t2.IDRFX = t1.IDRFX
                    and t2.ID > t1.ID); -- add only this condition in your query

一种方法是使用带有行号的子查询


一种方法是使用带有行号的子查询


没有解析函数

    with data as(
select 1 id, 384 idrfx, 1 docnum from dual union all
select 2 id, 384 idrfx, 1 docnum from dual union all
select 3 id, 384 idrfx, 2 docnum from dual union all
select 4 id, 385 idrfx, 1 docnum from dual 
)
,uniqueTuple as  (
select min(id) id from data
group by idrfx,docnum 
)

select d.* 
from data d
join uniqueTuple u on u.id = d.id 

没有解析函数

    with data as(
select 1 id, 384 idrfx, 1 docnum from dual union all
select 2 id, 384 idrfx, 1 docnum from dual union all
select 3 id, 384 idrfx, 2 docnum from dual union all
select 4 id, 385 idrfx, 1 docnum from dual 
)
,uniqueTuple as  (
select min(id) id from data
group by idrfx,docnum 
)

select d.* 
from data d
join uniqueTuple u on u.id = d.id 

关唯一的问题是我必须返回下载时间戳,所以这只解决了75%的问题:但是元组不再是唯一的了。如何确定给定元组的下载时间戳?如果您想要给定元组的下载时间戳的最小值或最大值,您可以将表本身连接起来,并以这种方式将下载时间戳添加到元组中。这是系统在运行时确定的信息。当系统执行此查询时,还需要显示下载时间戳关闭!唯一的问题是我必须返回下载时间戳,所以这只解决了75%的问题:但是元组不再是唯一的了。如何确定给定元组的下载时间戳?如果您想要给定元组的下载时间戳的最小值或最大值,您可以将表本身连接起来,并以这种方式将下载时间戳添加到元组中。这是系统在运行时确定的信息。当系统执行此查询时,它还需要显示标准SQL函数或MSSQL和ORACLE特有的下载时间戳行号?行号是标准窗口函数。它在几乎所有最新版本的DBMS中都可用。行号是标准SQL函数,或MSSQL和ORACLE特有的?行号是标准窗口函数。它在几乎所有最新版本的DBMS中都可用。我可能没有想到将last AND子句添加到NOT EXIST查询中!谢谢你,这解决了我的问题,用简单的SQL!出于好奇:在性能方面,哪一个更好?NOT EXISTS对性能有好处,但在oracle中,oracle 11g之后做了很多更改,oracle中的分析功能也更快。我可能没有想到在NOT EXIST查询中添加last and子句!谢谢你,这解决了我的问题,用简单的SQL!出于好奇:在性能方面,哪一个更好?不存在对性能有好处,但在oracle中,在oracle 11g之后进行了许多更改,并且oracle中的分析功能也更快。