在 Table1 中查找与 Table2 中的条件行匹配的行

Posted

技术标签:

【中文标题】在 Table1 中查找与 Table2 中的条件行匹配的行【英文标题】:find rows in Table1 that match criteria rows in Table2 【发布时间】:2015-07-22 17:24:19 【问题描述】:

我有两张桌子:

    T1 是一个数据表 列one不能有nulltwothree可以有nulls T2 是分类规则表 它具有与 T1 相同的列以及一个代表类别的 cat 列 这个想法是,前三列具有用于确定 T1 中的行如何以及是否应该分类的标准 T2 中的一行可能有 2 列以上的值,这意味着T1 中需要匹配多个条件(例如T1.two like "2*" and T1.three like "hi"

我想要一个查询来查找T1 中根据T2 中的条件匹配的行。这是一个例子:

+------+------+-------+
| T1                  |
+------+------+-------+
| one  | two  | three |
+------+------+-------+
| aaaa | 1111 |       |
| bbbb | 2222 |       |
| cccc |      | test  |
| dddd |      |       |
+------+------+-------+

+------+-----+-------+------+
| T2                        |
+------+-----+-------+------+
| one  | two | three | cat  |
+------+-----+-------+------+
| aaaa | *   | *     |    1 | -> all rows in T1 where column one equals aaaa
| *    | 2*  | *     |    2 | -> all rows in T1 where column two starts with 2
| *    | *   | test  |    3 | -> all rows in T1 where column three equals test
| *    | 3*  | hi    |    3 | -> all rows in T1 where column two starts with 3 AND column 3 equals hi
+------+-----+-------+------+

我在T2 中有*,因为我想说这些列中的值无关紧要。所以以第二行为例,我说的是匹配 T1 中的所有行,其中:

one 什么都可以 two 以 2 开头 three 什么都可以

我的想法是做一个模棱两可的连接并过滤匹配的行:

SELECT T1.one, T2.one, T1.two, T2.two, T1.three, T2.three, T2.id
FROM T1, T2
WHERE
    (T1.one Like [T2].[one])                             ' match column one
    AND (T1.two Is Null Or T1.two Like [T2].[two])       ' match column two; the "is null" is needed in case the value is not there in T1
    AND (T1.three Is Null Or T1.three Like [T2].[three]) ' match column three; the "is null" is needed in case the value is not there in T1

结果如下表。它部分有效,但返回不应该的行(标记如下)。

+--------+--------+--------+--------+----------+----------+----+
| Result                                                       |
+--------+--------+--------+--------+----------+----------+----+
| T1.one | T2.one | T1.two | T2.two | T1.three | T2.three | cat|
+--------+--------+--------+--------+----------+----------+----+
| aaaa   | aaaa   |   1111 | *      |          | *        |  1 | 
| aaaa   | *      |   1111 | *      |          | test     |  3 | -> THIS SHOULD NOT BE RETURNED
| bbbb   | *      |   2222 | 2*     |          | *        |  2 | 
| bbbb   | *      |   2222 | *      |          | test     |  3 | -> THIS SHOULD NOT BE RETURNED
| cccc   | *      |        | 2*     | test     | *        |  2 | -> THIS SHOULD NOT BE RETURNED
| cccc   | *      |        | *      | test     | test     |  3 | 
| dddd   | *      |        | 2*     |          | *        |  2 | -> THIS SHOULD NOT BE RETURNED
| dddd   | *      |        | *      |          | test     |  3 | -> THIS SHOULD NOT BE RETURNED
+--------+--------+--------+--------+----------+----------+----+

我已经开始了几个小时,但我不知道如何做我需要的。

我认为这不是一个特定于数据库的问题,但如果它很重要,我会尝试使用 MS Access 2013 来解决这个问题。

【问题讨论】:

我无法理解您想要什么...您能进一步解释一下吗?您想要 T1 中的行,其中 T2 中的等效字段为空或等于 T1? 你的表中真的有星号吗? 你应该在 WHERE 子句中使用 OR 而不是 AND @PatB:我添加了更多细节。我希望它有所帮助。 @Gene:是的,因为我想说这些列中的值不重要。 【参考方案1】:

据我所知,您有 2 个问题:您无法在计算字段上连接表。

-> T1 中第二列以 2 开头的所有行 -> T1 中第二列以 3 开头且第三列等于 hi 的所有行

不能这样做。

但是,我建议您使用 sql fiddle 来展示您的示例。

我已经为你做了。

http://sqlfiddle.com/#!9/bb1fc/2

【讨论】:

有一个用于 SQL 的 FIDDLE 站点?我这辈子你去哪儿了。我一直希望有这样的事情。我回家时会检查一下。谢谢!【参考方案2】:
SELECT T1.one, T2.one, T1.two, T2.two, T1.three, T2.three, T2.id
FROM T2 LEFT JOIN T1 
on t1.one = t2.one and t1.two = t2. two and t1.three = t2.three

除非您指定模式,否则您无法使用 like 比较列。

【讨论】:

这就是为什么我将* 放在T2 的值中,这样我就可以使用like【参考方案3】:
SELECT T1.one, T2.one, T1.two, T2.two, T1.three, T2.three, T2.ID
FROM T1, T2
WHERE (t1.one LIKE t2.one + '*'
AND t1.two LIKE t2.two + '*'
AND t1.three LIKE t2.three + '*')
OR t1.one LIKE t2.one + '*'
OR t1.two LIKE t2.two + '*'
OR t1.three LIKE t2.three + '*'

【讨论】:

可能存在T2 中的一行在两列中有条件的情况,在这种情况下,两者都需要匹配才有效。 我有更多的列,我觉得这种 SQL 很快就会变得复杂。【参考方案4】:

为了将来参考,我想我找到了一个可行的答案:http://sqlfiddle.com/#!9/595eb/1。

我没有在T2 中使用*(通配符),而是使用null,然后在查询中检查该值是否为null。这似乎具有预期/预期的结果。

WHERE
  (T2.one is null or T1.one = T2.one) AND
  (T2.two is null or T1.two like T2.two) AND
  (T2.three is null or T1.three like T2.three);

如果T2 中的多行与T1 中的一行匹配,则会出现重复,所以我仍在努力解决这个问题。

【讨论】:

以上是关于在 Table1 中查找与 Table2 中的条件行匹配的行的主要内容,如果未能解决你的问题,请参考以下文章

查询以获取 table1 中每一行的结果,其中包含 N 个最大记录的子查询,找到满足 table2 中的条件

JPA 中的条件 where 子句

Mysql更新table1与table2比较

mysql中sql语句查询的同时根据条件将数据插入到另一个表的做法?

仅当与 table2 中的 column3 匹配时才更新 table1 中的 column1

MySQL:如果 table1 中的行存在,则在 table2 上插入行