【问题标题】:MySql Show values not in the second tableMySql显示不在第二个表中的值
【发布时间】:2013-11-30 10:48:57
【问题描述】:

我正在尝试向预订了一项活动的人提供其他活动的门票。我有两张类似的桌子

---Concerts----------------
|  ConcertID  | Concert   |
---------------------------
|   101       | Mozart    |
|   102       | Beethoven |
|   103       | Chopin    |
---------------------------

---Tickets--------------------------------------------
| TicketNum |  Name      |  email       | ConcertID  | 
------------------------------------------------------
| 5001      | Amy Jones  | aaa@aaa.com  |  101       |
| 5002      | Amy Jones  | aaa@aaa.com  |  102       |
| 5003      | John Doe   | bbb@bbb.com  |  102       |
| 5004      | Adam Smith | ccc@ccc.com  |  101       |
| 5005      | Jerry Coe  | ddd@ddd.com  |  102       |
------------------------------------------------------

我正在尝试构建一个类似的语句

SELECT Tickets.email, Concerts.ConcertID, Concerts.Concert FROM Tickets, Concerts 
WHERE (Show Concerts Not Booked)
AND Concerts.ConcertID = Tickets.ConcertID 
AND email = "bbb.com"  

然后这个节目会将 John Doe 没有预定的两场音乐会返回到,即 101 Mozart 和 102 Chopin。

这是我正在努力解决的(未预订的演唱会)

我可以构造一个查询来显示他预订了哪些音乐会的交集,但我无法显示他没有预订的音乐会。

感谢任何帮助。

【问题讨论】:

    标签: mysql join intersection


    【解决方案1】:
    Select c.ConcertID, C.Concert
    From Concerts c
    Left join Tickets t On t.ConcertID = c.ConcertID
    Where t.ConcertID is null and t.Name = 'John Doe'
    

    会这样做。

    没有别名可能会使发生的事情更清楚

    Select Concerts.ConcertID, Concerts.Concert
    From Concerts
    Left join Tickets On Tickets.ConcertID = Concerts.ConcertID
    Where Tickets.ConcertID is null and Tickets.Name = 'John Doe'
    

    这样想,如果您想要一份所有音乐会的清单以及约翰是否买了票 你会做的

    Select *
    From Concerts
    Left join Tickets On Tickets.ConcertID = Concerts.ConcertID
    Where Tickets.Name = 'John Doe'
    

    得到

    101 Mozart    NULL  NULL    NULL        NULL 
    102 Beethoven 5003 John Doe bbb@bbb.com 102
    103 Chopin    NULL NULL     NULL        NULL
    

    所以 where 语句中的额外条件过滤掉了不存在票证的行。

    这很烦人,在玩了@JungSu Heo 的 sql fiddle 之后,我发现这很有效

    Select *
    From Concerts c
    Left join Tickets t On t.ConcertID = c.ConcertID and t.Name = 'John Doe'
    Where t.ConcertID is null
    

    经过一番思考后说得通,因为 John Doe 在 where 子句中的空值被切掉了。在 join 子句中做,那么 John Doe 只用于约束外连接。

    谢谢你学到了一些东西,虽然我通常不会看到这样的东西,因为我有一个姓名/预订者类型表。

    【讨论】:

    • 尝试过(将 C 更改为 Concerts)但收到错误消息 - MySQL 返回了一个空结果集(即零行)。
    • 我已经试过了 - SELECT Concerts.ConcertID, Concerts.Concert FROM Concerts LEFT JOIN Tickets t ON t.ConcertID = Concerts.ConcertID WHERE Con​​certs.ConcertID IS NULL AND t.Name = 'John Doe' LIMIT 0 , 30 - 但我得到一个空结果
    • 哎呀,等等错过了别名。您的尝试失败了,因为您查找了所有预订了不存在的音乐会的门票...
    • 我用它来显示 John Doe 预订的音乐会 - 选择 c.ConcertID, c.Concert From Concerts c Left join Tickets t On t.ConcertID = c.ConcertID Where t. Name = 'John Doe' - 但无法获得他没有预订的那些
    • @TonyHopkinson Tony,这里是带有 OP 数据的 sqlfiddle。 sqlfiddle.com/#!9/9fd32/2/0我无法再跟进了。现在是星期六晚上 8 点。我在办公室工作。是时候回家了。
    【解决方案2】:

    我不明白为什么 Tony 的查询不起作用。你能试试这个吗?

    SELECT c.ConcertID, c.Concert
    FROM Concerts c
    WHERE c.ConcertID NOT IN 
    (
        SELECT ConcertID
        FROM Tickets
        WHERE Name = 'John Doe'
    )
    

    如果您将数据发布到 http://www.sqlfiddle.com/,我们将不胜感激。易于测试。

    【讨论】:

    • Ton'y 查询不起作用,因为他是个笨蛋,错过了别名。 :) 你的会起作用,我总是直接使用左连接,因为有时 DBMS 会以这种形式表现得像猪耳朵,最终会得到一些表现不佳的东西。
    • 谢谢托尼!和@user3051841,托尼的比我的好。我只是想检查你的数据,确实有 101 和 103 票 Doe 没有使用海峡前进 'NOT IN' 预订(很容易理解,但在 MySQL 中这有点慢)
    • 如果不存在则创建表Concerts (ConcertID int(11) NOT NULL, Concert varchar(255) NOT NULL) ENGINE=MyISAM 默认字符集=utf8;音乐会数据 - INSERT INTO Concerts (ConcertID, Concert) VALUES (101, 'Mozart'), (102, 'Beethoven'), (103, 'Chopin');
    • 如果不存在则创建表 Tickets ( TicketNum int(11) NOT NULL, Name varchar(255) NOT NULL, email varchar(255) NOT NULL, ConcertID int(11) NOT NULL ) 引擎=MyISAM 默认字符集=utf8;插入TicketsTicketNumNameemailConcertID)值(5001,'Amy Jones','aaa@aaa.com',101),(5002,'Amy Jones', 'aaa@aaa.com', 102), (5003, 'John Doe', 'bbb@bbb.com', 102);
    • @user3051841 等一下。我正在检查。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-25
    • 2019-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多