【问题标题】:Comparing tables and getting non matching values比较表并获得不匹配的值
【发布时间】:2015-12-09 13:34:30
【问题描述】:

我对 SQL 很陌生,我无法让它工作我在下面有这两个表

Table A                                 Table B
    _________________               _________________
    | A   | 2015-10-4               | B   | 2015-11-6
    | B   | 2015-11-4               | C   | 2015-05-4
    | C   | 2015-05-6               | D   | 2015-05-8
    | D   | 2015-05-7               | C   | 2015-05-5

我正在尝试编写一个存储过程,该过程将从表 B 中获取日期小于表 A 的所有字母以及表 B 中不存在的任何字母。

这是我目前所拥有的

    SELECT      *
    FROM        A q JOIN 
                B c ON q.Letter = c.Letter AND q.Date > c.Date OR c.Letter IS NULL

这会返回 C,但我不能让它也返回 A。尝试加入和比较表格仍然让我感到困惑。

我不想要重复的行,我期望的结果会返回

| A   | 2015-10-4 
| C   | 2015-05-6

编辑

我现在遇到了一个问题,如果我有这样的情况

        Table A                           Table B
    _________________               _________________
    | A   | 2015-10-4               | B   | 2015-11-6
    | B   | 2015-11-4               | C   | 2015-05-4
    | C   | 2015-05-6               | D   | 2015-05-8
    | D   | 2015-05-7               | C   | 2015-05-5
                                    | C   | 2015-05-7

由于某种原因,它仍然会返回 C。使用 a.date > max(b.date) 不起作用,因为 max 不能那样使用。我想假设最大日期可以在表 B 中的任何地方。

所以现在我的新结果是

| A   | 2015-10-4 

但我仍然得到 A 和 C。

【问题讨论】:

  • 您应该发布您想要的结果,以便我们了解您是否想要重复的行、哪些日期等
  • @Lamak 已编辑并获得预期结果!谢谢!

标签: tsql sql-server-2012


【解决方案1】:

你应该使用LEFT JOIN:

SELECT DISTINCT A.letter, A.[Date]
FROM dbo.TableA A
LEFT JOIN dbo.TableB B
    ON A.letter = B.letter
WHERE B.[Date] < A.[Date] OR B.letter IS NULL;

更新

您应该将您的要求解释为:“从表 B 中获取所有日期小于...的字母”

SELECT DISTINCT A.letter, A.[Date]
FROM dbo.TableA A
LEFT JOIN (SELECT letter, MAX([Date]) [Date]
           FROM dbo.TableB
           GROUP BY letter) B
    ON A.letter = B.letter
WHERE B.[Date] < A.[Date] OR B.letter IS NULL;

【讨论】:

  • 天哪,我不敢相信我看了这么简单的东西。出于某种原因,我无法围绕它进行思考。我最初在ON 部分中有 Date
  • 我编辑了我的问题,遇到了一个我没有预料到的特殊情况。任何关于为什么会发生这种情况的见解都会很棒!
  • 谢谢!我想在我开始输入一些虚拟数据之前,我从未想过这种情况。实际上,我已经学到了很多关于连接和子查询如何工作的知识。
【解决方案2】:

我会选择 UNION / UNION ALL,这样您就可以获得第一个条件的结果子集 + 第二个条件的结果子集。 类似的东西应该可以完成这项工作:

sqlite> create table A (letter, my_date);
sqlite> create table B (letter, my_date);
sqlite> insert into A values ('A', '2015-10-04');
sqlite> insert into A values ('B', '2015-11-04');
sqlite> insert into A values ('C', '2015-05-06');
sqlite> insert into A values ('D', '2015-05-07');
sqlite> insert into B values ('B', '2015-11-06');
sqlite> insert into B values ('C', '2015-05-04');
sqlite> insert into B values ('D', '2015-05-08');
sqlite> insert into B values ('C', '2015-05-05');
A           2015-10-04
sqlite> select B.* from A, B where A.letter = B.letter and B.my_date < A.my_date UNION ALL select A.* from A where not exists (select 1 from B where B.letter=A.letter);
letter      my_date
----------  ----------
C           2015-05-04
C           2015-05-05
A           2015-10-04

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-10
    • 2012-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-02
    相关资源
    最近更新 更多