SQL 查询 Return 不同的值

SQL Where Query to Return Distinct Values

我有一个内置初始 Select 选项的应用程序,只允许我从“位置”部分输入。我有具有重复值的行。我试图为每个不同的值获取只有一个记录的列表,但不确定如何使该语句起作用。我找到了一个几乎可以解决问题的方法,但它没有给我任何有错误的行。我假设由于 = 所以只需要一种方法来为每个符合我的 where 标准的人获得一个。示例如下。

初始数据集

Date      | Name   | ANI         | CallIndex   | Duration
---------------------------------------------------------    
2/2/2015  | John   | 5555051000  | 00000.0001  | 60  
2/2/2015  | John   |             | 00000.0001  | 70 
3/1/2015  | Jim    | 5555051001  | 00000.0012  | 80  
3/4/2015  | Susan  |             | 00000.0022  | 90 
3/4/2015  | Susan  | 5555051002  | 00000.0022  | 30  
4/10/2015 | April  | 5555051003  | 00000.0030  | 35 
4/11/2015 | Leon   | 5555051004  | 00000.0035  | 10 
4/15/2015 | Jane   | 5555051005  | 00000.0050  | 20 
4/15/2015 | Jane   | 5555051005  | 00000.0050  | 60 
4/15/2015 | Kevin  | 5555051006  | 00000.0061  | 35

我要查询的内容 Return

Date      | Name   | ANI         | CallIndex   | Duration
---------------------------------------------------------    
2/2/2015  | John   | 5555051000  | 00000.0001  | 60
3/1/2015  | Jim    | 5555051001  | 00000.0012  | 80
3/4/2015  | Susan  | 5555051002  | 00000.0022  | 30
4/10/2015 | April  | 5555051003  | 00000.0030  | 35
4/11/2015 | Leon   | 5555051004  | 00000.0035  | 10
4/15/2015 | Jane   | 5555051005  | 00000.0050  | 20
4/15/2015 | Kevin  | 5555051006  | 00000.0061  | 35

这是我能够得到的,但是当我 运行 它时,我没有得到确实具有 dups callindex 值的行。持续时间并不重要,它们永远不会匹配,所以如果它有助于使用它作为过滤器进行查询,那很好。我添加了模拟数据来提供帮助。

use Database
SELECT * FROM table
WHERE Date between '4/15/15 00:00' and '4/15/15 23:59'
and callindex in
                (SELECT callindex 
                 FROM table 
                 GROUP BY callinex 
                 HAVING COUNT(callindex) = 1)

如有任何帮助,我们将不胜感激。

好的,在这里每个人的帮助下,我能够使查询在 SQL 内完美运行。也就是说,显然我正在尝试的应用程序具有内置字符限制,并且以下查询太长。就限制而言,这是我必须使用的查询,我必须能够同时搜索两个 ID,因为有些 ID 很少同时被一个或另一个标记。我希望有人可以帮我缩短它?

use Database
select * from tblCall
WHERE 
    flddate between '4/15/15 00:00' and '4/15/15 23:59'
    and fldAgentLoginID='1234'
    and fldcalldir='incoming'
    and fldcalltype='external'
    and EXISTS (SELECT * FROM (SELECT MAX(fldCallName) AS fldCallName, fldCallID FROM tblCall GROUP BY fldCallID) derv WHERE tblCall.fldCallName = derv.fldCallName AND tblCall.fldCallID = derv.fldCallID)
or
    flddate between '4/15/15 00:00' and '4/15/15 23:59'
    and '4/15/15 23:59'
    and fldPhoneLoginID='56789'
    and fldcalldir='incoming'
    and fldcalltype='external'
    and EXISTS (SELECT * FROM (SELECT MAX(fldCallName) AS fldCallName, fldCallID FROM tblCall GROUP BY fldCallID) derv WHERE tblCall.fldCallName = derv.fldCallName AND tblCall.fldCallID = derv.fldCallID)

从您的样本来看,您似乎可以只排除 ANI 列中没有值的行。如果是这种情况,您可以简单地执行以下操作:

use Database
SELECT * FROM table
WHERE Date between '4/15/15 00:00' and '4/15/15 23:59'
and ANI is not null

如果这对您不起作用,请告诉我,我会看看我还能做些什么。

编辑: 你已经让它听起来像 CallIndex 与 Duration 相结合是一个独特的价值。这对我来说似乎有点怀疑,但如果是这样的话,你可以这样做:

use Database
SELECT * FROM table
WHERE Date between '4/15/15 00:00' and '4/15/15 23:59'
and cast(callindex as varchar(80))+'-'+cast(min(duration) as varchar(80)) in
                (SELECT cast(callindex as varchar(80))+'-'+cast(min(duration) as varchar(80)) 
                 FROM table 
                 GROUP BY callindex)

在你的数据中,为什么不这样做呢?

SELECT *
FROM table
WHERE Date >= '2015-04-15' and Date < '2015-04-16'
      ani is not null;

如果空白值只是巧合,那么使用 where 子句就会出现问题。如果结果是完全重复的(no 列具有不同的值),那么您可能无法仅使用 where 子句来执行您想要的操作——除非您使用的是 SQLite, Oracle 或 Postgres。

您可以使用两个关键字来获取非重复数据,DISTINCTGROUP BY。在这种情况下,我会使用 GROUP BY,但您应该仔细阅读两者。

此查询按 CallIndex 对所有记录进行分组,并为每个其他列取 MAX 值,应该会为您提供所需的结果:

SELECT MAX(Date) AS Date, MAX(Name) AS Name, MAX(ANI) AS ANI, CallIndex
FROM table
GROUP BY CallIndex

编辑

因为你不能直接使用 GROUP BY 但你可以在 WHERE 子句中使用任何 SQL 你可以这样做:

SELECT *
FROM table
WHERE EXISTS
(
    SELECT *
    FROM 
    (
       SELECT MAX(Date) AS Date, MAX(Name) AS Name, MAX(ANI) AS ANI, CallIndex
       FROM table
       GROUP BY CallIndex   
    ) derv
    WHERE table.Date = derv.Date 
         AND table.Name = derv.Name
         AND table.ANI = derv.ANI
         AND table.CallIndex = derv.CallIndex
)

这会选择 table 中存在 GROUP BY 中匹配行的所有行。

它不会是完美的,如果任何两行完全匹配,您仍然会有重复项,但这是限制条件下的最佳结果。

如果约束是我们只能添加到 WHERE 子句,我认为这是不可能的,因为有 2 个完全相同的行:

 4/15/2015 | Jane   | 5555051005  | 00000.0050    
 4/15/2015 | Jane   | 5555051005  | 00000.0050 

是否可以在 WHERE 中添加 HAVING 或 GROUP BY?或者可能将 SELECT 联合到另一个 SELECT 语句?这可能会带来一些额外的可能性。

也许有工会:

SELECT *
FROM table
GROUP BY Date, Name, ANI, CallIndex
HAVING ( COUNT(*) > 1 )

UNION

SELECT *
FROM table
WHERE Name not in (SELECT name from table
GROUP BY Date, Name, ANI, CallIndex
HAVING ( COUNT(*) > 1 ))