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。
您可以使用两个关键字来获取非重复数据,DISTINCT
或 GROUP 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 ))
我有一个内置初始 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。
您可以使用两个关键字来获取非重复数据,DISTINCT
或 GROUP 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 ))