【问题标题】:Pick exact records选择准确的记录
【发布时间】:2016-11-10 05:06:32
【问题描述】:
INSERT INTO filerecord (fname,
                                  lname,
                                  transdate,
                                  memberid)
 VALUES ('tyler',
         'smith',
         TO_DATE ('07/01/2016', 'mm/dd/yyyy'),
         '111');

我得到以下结果:

fname      lname              email
fernando    hernandez   fh@yahoo.com
fernando    hernandez   ts@hotmail.com

由于 transdate 条款,IT 不应显示 Tyler Smith 的姓名和电子邮件。我正在找人给我只有费尔南多的结果。 我无法更改表格的结构。

【问题讨论】:

  • 分享你得到的输出和你的目标。
  • 我得到以下结果: fname lname email fernando hernandez fh@yahoo.com fernando hernandez ts@hotmail.com
  • 当然。例如,将AND b.fname = e.fname AND b.lname = e.lname 添加到您的查询中会修复它。但是您不想只编写适用于您的查询的连接...您想编写 正确 连接。也就是说,找出每个表上的 PRIMARY KEY 或其他 UNIQUE KEY 是什么,并在您的联接中使用其中一个。
  • 将您的问题编辑为 Testing.....没有任何效果。我已经完成了尝试!不会受到好评。

标签: sql oracle join duplicates inner-join


【解决方案1】:

你得到一个笛卡尔积。

您在两个表中都有两个带有 memberid = '111' 的条目,所以这个条件

 AND b.memberid = e.memberid

将您过滤到 4 行 --

  • 与 Tyler Smith 的人加入了 Tyler Smith 的电子邮件
  • Fernando Hernandez 的一个加入到 Fernando Hernandez 的电子邮件中,
  • 与 Tyler Smith 的一个人加入了 Fernando Hernandez 的电子邮件并
  • Fernando Hernandez 加入了 Tyler Smith 的电子邮件

那么,这个条件:

AND b.transdate >= TO_DATE ('07/02/2016', 'mm/dd/yyyy');

排除其中两个,但不排除其他两个。

您需要更好的数据模型和/或更精确的方法来连接您的两个表。

一般来说,每当您连接两个表时,其中一个表应指定其所有主键列以避免此类错误。 (与往常一样,也有例外)。

【讨论】:

  • 我也知道。我现在无法更改结构,因为它有数百万条记录。我认为那里的一些天才可以为我提供正确的电子邮件地址记录。
  • 可以在过程中使用某些逻辑并获得正确的输出吗?
【解决方案2】:

事实并非如此。我刚刚创建了一个新表并进行了检查。

表格成员

create table member (programid varchar(10), memberid int, fname varchar(10), lname varchar(10), email varchar(25))

内容

+-----------+----------+----------+-----------+----------------+
| PROGRAMID | MEMBERID |  FNAME   |   LNAME   |     EMAIL      |
+-----------+----------+----------+-----------+----------------+
| BLUE      |      111 | tyler    | smith     | ts@hotmail.com |
| GREEN     |      111 | fernando | hernandez | fh@yahoo.com   |
+-----------+----------+----------+-----------+----------------+

表格文件记录

create table filerecord (fname varchar(10), lname varchar(10), transdate date, memberid int);

内容

+-------+-------+-----------+----------+
| FNAME | LNAME | TRANSDATE | MEMBERID |
+-------+-------+-----------+----------+
| tyler | smith | 7/1/2016  |      111 |
+-------+-------+-----------+----------+

上次查询

SELECT b.fname, b.lname, e.email
     FROM filerecord b, member e
     WHERE     b.memberid IN ('111')
     AND b.memberid = e.memberid
     AND b.transdate >= TO_DATE ('07/02/2016', 'mm/dd/yyyy');

结果 -

没有选择任何行。

【讨论】:

  • fernando 在bouncedfundingfile 记录表中的什么位置?
【解决方案3】:

由于memberid 不是唯一标识符,因此没有理由期望像b.memberid = e.memberid 这样的连接条件会带来好处。

相反,您似乎建议(或相信)(memberid, fname, lname) 应该是唯一标识符。所以,在连接条件中使用它:

... WHERE ...   AND b.memberid = e.memberid 
                AND b.fname    = e.fname 
                AND b.lname    = e.lname 
          ...

像这样:

SQL> SELECT b.fname, b.lname, e.email
  2       FROM filerecord b, member e
  3       WHERE     b.memberid IN ('111')
  4       AND b.memberid = e.memberid
  5       AND b.fname    = e.fname
  6       AND b.lname    = e.lname
  7       AND b.transdate >= TO_DATE ('07/02/2016', 'mm/dd/yyyy');

FNAME                LNAME                EMAIL
-------------------- -------------------- --------------------
fernando             hernandez            fh@yahoo.com

1 row selected.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-12
    • 2022-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多