一位同事为我准备了一张我需要映射数据的表,而表包含两个字段OP_ID和BillType。理论上,两者之间应该存在一对一的对应关系:每个Op_ID应该只有一种账单类型。
然而,当我开始使用它时,我注意到有不同BillTypes的重复OP_ID。 E.g:
OP_Id BillType
007a000v9GWkAAM BillReady
007a000v9GWkAAM RateReady
首先,我构建了一个查询,将数据分组为ID和BillTypes的唯一组合:
SELECT OP_ID, BillType
FROM MappingTable
GROUP BY OP_ID, BillType
足够简单。该集应该并且确实包括上述两个记录。然后,我围绕此包装另一个查询来计算聚合数据集中的OP_Ids。从理论上讲,任何具有多个BillType的OP_ID都应该出现两次,因此它应该返回一个>对吧?
SELECT OP_ID, BillType, Count(OP_ID)
FROM
(
SELECT OP_ID, BillType
FROM MappingTable
GROUP BY OP_ID, BillType
) Base
GROUP BY OP_ID, BillType
HAVING Count(OP_ID) > 1
但是这个查询什么都不返回。更令人费解的是:当我删除HAVING子句并将查询限制为仅提取上述OP_ID时,因为我已经知道它是一个骗局,我得到的是:
OP_ID BillType CountOfOP_IDs
007a000v9GWkAAM BillReady 1
007a000v9GWkAAM RateReady 1
因此OP_ID 007a000v9GWkAAM显然有两条记录,但SQL只计算一条!
这看起来很简单,我确信我只是缺少一些关于COUNT()如何工作的基本知识。作为参考,我正在研究SQL Server 2014,两列都是nvarchar。我还确认SQL将两个记录中的OP_ID评估为相同。任何人都知道为什么会这样吗?
答案 0 :(得分:4)
Count计算已分组为一行的行数。只需从外部组删除帐单类型。
另请参阅count distinct选项。这可能会更容易。
答案 1 :(得分:3)
声明
SELECT OP_ID, BillType
FROM MappingTable
GROUP BY OP_ID, BillType
是很长的路要走
SELECT DISTINCT OP_ID, BillType
FROM MappingTable
如果您现在拥有OP_ID
和BillType
的不同组合,则在这两个字段上添加新的GROUP BY
将无效。
SELECT ...
FROM ( SELECT DISTINCT OP_ID, BillType
FROM MappingTable
) Base
GROUP BY OP_ID, BillType
HAVING Count(OP_ID) > 1
新的“群组”将全部由内部SELECT
的一行组成,因此COUNT
将始终为1,这意味着Count(OP_ID) > 1
始终为false,您将不会返回任何内容
也许您打算查找具有多个OP_Id
值的BillType
值。如果是这样,您应该从BillType
中删除GROUP BY
,suggested by @DonKirkby。
如果您对此感兴趣,那么您可以通过检索第一个和最后一个BillType
值来获得结果中BillType
个值的两个示例(通常情况下很好)研究,至少)。
SELECT OP_ID, COUNT(*), MIN(BillType), MAX(BillType)
FROM ( SELECT DISTINCT OP_ID, BillType
FROM MappingTable
) Base
GROUP BY OP_ID
HAVING COUNT(*) > 1
您可以使用COUNT(DISTINCT ...)
缩短整个语句,也可以suggested by @DonKirkby缩短整个语句。
SELECT OP_ID, COUNT(DISTINCT BillType), MIN(BillType), MAX(BillType)
FROM MappingTable
GROUP BY OP_ID
HAVING COUNT(DISTINCT BillType) > 1
答案 2 :(得分:1)
你的方法很有意义。我的猜测是OP_ID
值略有不同 - 可能是由于编码问题或角色外观相似。
这很容易找到。这个查询返回了什么?
select mt.*
from mappingtable
where op_id = '007a000v9GWkAAM';
顺便提一下,您可以将查询简化为:
SELECT OP_ID
FROM MappingTable
GROUP BY OP_ID
HAVING MIN(BillType) <> MAX(BillType);
如果您想查看BillType
值,请将GROUP_CONCAT(BillType)
添加到SELECT
。
编辑:
以上内容都是正确的,但您的查询不起作用,因为外部查询按OP_ID
和BILL_TYPE
进行分组。试试这个版本:
SELECT OP_ID, Count(OP_ID)
FROM (SELECT OP_ID, BillType
FROM MappingTable
GROUP BY OP_ID, BillType
) Base
GROUP BY OP_ID
HAVING Count(OP_ID) > 1;
您没有返回任何行,因为您要对相同的键进行两次分组。子查询删除重复项,因此外部的计数始终为1。
答案 3 :(得分:1)
SELECT *
FROM MappingTable
WHERE OP_ID in (SELECT OP_ID
FROM (SELECT OP_ID, count(*) ct
FROM MappingTable
GROUP BY OP_ID)
WHERE ct > 1)
对于BOTH列,没有(至少在您的示例中)重复,只是OP_ID的意外重复。