SQL函数在两个表之间创建一对一的匹配?

SQL函数在两个表之间创建一对一的匹配?,sql,sql-server,join,Sql,Sql Server,Join,我正在尝试加入两个表。表A约有145k行,而表B约有205k行 它们共有两列(即ISIN和date)。但是,当我执行此查询时: SELECT A.*, B.column_name FROM Table_A JOIN Table_B ON A.date = B.date WHERE A.isin = B.isin 我有一张超过147k行的桌子。怎么可能呢?它不应该返回一个最多有145k行的表吗?在联接条件下保持两个表的日期列格式相同,您应该会得

我正在尝试加入两个表。表A约有145k行,而表B约有205k行

它们共有两列(即ISIN和date)。但是,当我执行此查询时:

SELECT A.*,
       B.column_name

FROM   Table_A
       JOIN
       Table_B ON A.date = B.date

WHERE  A.isin = B.isin

我有一张超过147k行的桌子。怎么可能呢?它不应该返回一个最多有145k行的表吗?

在联接条件下保持两个表的日期列格式相同,您应该会得到预期的结果

Select A.*, B.column_name
from Table_A
join Table_B on to_date(a.date,'DD-MON-YY')  = to_date(b.date,'DD-MON-YY') 
 where A.isin = B.isin

您看到的情况表明,对于
表A
中的一些记录,
表B
中有多条记录满足联接条件(在
(日期,isin)
元组上相等)

要展示这些记录,您可以执行以下操作:

select B.date, B.isin
from Table_A
join Table_B on A.date = B.date and A.isin = B.isin
group by B.date, B.isin
having count(*) > 1
由您定义如何处理这些重复项。例如:

  • 如果重复项在列
    列\u name
    中具有不同的值,则可以决定提取最大值或最小值

  • 或者使用另一列筛选副本中的顶部或下部记录

  • 如果重复项是真正的重复项,则可以在子查询中使用
    select distinct
    ,在加入之前将其删除

  • 。。。其他解决方案是可能的


    • 重复的可能性已经在讨论中

      当数以百万计的记录用于连接时,通常是由于不良的
      心脏病估计
      , 记录返回不准确

      为此,只需更改加入顺序

      SELECT A.*,
             B.column_name
      FROM   Table_A
             JOIN
             Table_B ON A.isin = B.isin 
          and
      A.date = B.date
      
      还要在这两个表上创建非聚集索引

      Create NonClustered index isin_date_table_A on Table_A(isin,date)include(*Table_A)
      
      *Table_A=逗号分隔列表Table_结果集中需要的列

      Create NonClustered index isin_date_table_B on Table_B(isin,date)include(column_nameA)
      
      更新统计表\u A


      updatestatistics Table\u B

      如果希望每个表A有一行,请使用
      outer apply

      SELECT A.*,
             B.column_name
      FROM Table_A a OUTER APPLY
           (SELECT TOP (1) b.*
            FROM Table_B b
            WHERE A.date = B.date AND A.isin = B.isin
            ORDER BY ?  -- you can specify *which* row you want when there are duplicates
           ) b;
      
      外部应用
      实现横向连接。
      TOP(1)
      确保最多返回一行。
      外部
      (与
      交叉
      相反)确保没有过滤掉任何内容。在本例中,还可以将其表述为相关子查询

      尽管如此,您的数据似乎并不是您真正期望的。你应该弄清楚复制品是从哪里来的。起点是:

      select b.date, b.isin, count(*)
      from tableb b
      group by b.date, b.isin
      having count(*) >= 2;
      

      这将向您显示重复项,这样您就可以知道如何处理它们。

      不,如果同一日期和isin存在重复记录,则每个连接将获得2行或更多行。不知道您的表结构,但使用日期连接不是很好的做法,如果可能,请使用表中的整数值连接。关于行数超出预期的原因,表中可能存在重复记录,也需要过滤掉。这是常见问题解答。在考虑发帖之前,请始终用谷歌搜索你的错误消息或你的问题/问题/目标的许多清晰、简洁和准确的措辞,有/没有你的特定字符串/名称和网站:stackoverflow.com和标签,并阅读许多答案。如果你发布一个问题,用一句话作为标题。请参见文本上方的投票箭头(&S)。PS请在代码问题中给出一个--cut&paste&runnable代码;示例输入(作为初始化代码)以及所需和实际输出(包括逐字错误消息);标签和版本;清晰的说明和解释。