【问题标题】:how to get distinct value for each table in a join如何为连接中的每个表获取不同的值
【发布时间】:2017-08-27 16:25:21
【问题描述】:

我正在为活动预订网站建立一个数据库。现在我有与 (eventTickets, eventSponsors, eventGuests) TABLE 的一对多关系相关的 EVENTS 表。

CREATE TABLE EVENT (
           EVENT_ID INTEGER NOT NULL AUTO_INCREMENT,
           ORGANIZER_ID INTEGER NOT NULL,
          name VARCHAR(30) NOT NULL,
          picture VARCHAR(50) NULL,
          venue VARCHAR(50) NOT NULL,
         city VARCHAR(30) NOT NULL DEFAULT Ethiopia,
         sub_city VARCHAR(50) NULL,
         location VARCHAR(50) NOT NULL,
        category VARCHAR(50) NOT NULL,
        start_date DATE NOT NULL,
        end_date DATE NOT NULL,
        longitude DOUBLE NULL,
        latitude DOUBLE NULL,
        status VARCHAR(15) NOT NULL DEFAULT DRAFT,
        discription TEXT NOT NULL,
       country VARCHAR(30) NOT NULL DEFAULT Ethiopia,
        end_time TIME NOT NULL,
       start_time TIME NULL,
       created_on TIMESTAMP NOT NULL DEFAULT TIMESTAMP(),
       PRIMARY KEY (EVENT_ID),
      FOREIGN KEY (ORGANIZER_ID) REFERENCES organizer(ORGANIZER_ID) ON DELETE CASCADE ON UPDATE CASCADE

     ) ENGINE=INNODB;

     CREATE TABLE SPONSORS  (
           SPONSOR_ID INTEGER NOT NULL AUTO_INCREMENT,
            EVENT_ID INTEGER NOT NULL,
           name VARCHAR(50) NOT NULL,
          image VARCHAR(50) NULL,
          PRIMARY KEY (SPONSOR_ID),
    FOREIGN KEY (EVENT_ID) REFERENCES event(EVENT_ID) ON DELETE CASCADE ON UPDATE CASCADE

     ) ENGINE=INNODB;



        CREATE TABLE GUESTS (
          GUEST_ID INTEGER NOT NULL AUTO_INCREMENT,
         first_name VARCHAR(30) NOT NULL,
         last_name VARCHAR(30) NOT NULL,
        aka_name VARCHAR(50) NULL,
        title VARCHAR(15) NULL,
         bio VARCHAR(100) NULL,
        image VARCHAR(50) NULL,
        EVNT_ID INTEGER NOT NULL,
        PRIMARY KEY (GUEST_ID),
       FOREIGN KEY (EVENT_ID) REFERENCES event(EVENT_ID) ON DELETE CASCADE ON UPDATE CASCADE

     ) ENGINE=INNODB;

        CREATE TABLE EVENT_TICKETS (
            TICKET_ID INTEGER NOT NULL AUTO_INCREMENT,
            EVENT_ID INTEGER NOT NULL,
            name VARCHAR(20) NOT NULL,
            type VARCHAR(20) NOT NULL,
           price FLOAT(4) NOT NULL,
           quantity INTEGER NOT NULL,
          discription VARCHAR(255) NOT NULL,
          sale_start DATE NOT NULL,
          sale_end DATE NOT NULL,
        active BOOL NOT NULL DEFAULT 0,
        available INTEGER NOT NULL,
        created_on TIMESTAMP NOT NULL DEFAULT NOW(),
        PRIMARY KEY (TIK_ID)
        FOREIGN KEY (EVENT_ID) REFERENCES event(EVENT_ID) ON DELETE CASCADE ON UPDATE CASCADE

     ) ENGINE=INNODB;

现在我有了事件表

      EVENT_ID | NAME
        1      | firstEvent
        2      | secondEvent

赞助商表

  SPONSOR_ID | EVENT_ID | name
       1     |    1      |    firstEventSponsor
       2     |    2      |   secondEventSponsor   

客人桌

GUEST_ID | EVENT_ID | first_name  | last_name
   1     |     1    |  firstEvent | guest
   2     |     2    |  secondEvent| guest

和票表

TICKET_ID | EVENT_ID | type  
   1     |     1    |  free  
   2     |     2    |  secondEvent
   3     |     1    |  paid

如果记录存在,我想从其他每个表中获取具有特定事件的所有相关字段,如果没有记录,则为 NULL。当我进行连接时,我得到一个重复其他表记录的结果集,直到结果集表行计数的最大返回匹配

这是我的加入

   SELECT  `event`.`EVENT_ID` AS 'eventId' ,`event`.`name` AS 'eventName' , `venue` `TICKET_ID` AS 'ticketId', `eventTicket`.`type` AS 'ticketType',
      `eventGuest`.`GUEST_ID` AS 'guestId',  CONCAT(`eventGuest`.`first_name`, " ", `eventGuest`.`last_name`) AS 'guestName', 
        `eventSponsor`.`SPONSOR_ID` AS 'sponsorId', `eventSponsor`.`name` AS 'sponsorName', 
    FROM `event`

    LEFT OUTER JOIN `eventTicket` ON `event`.`EVENT_ID` = `eventTicket`.`EVENT_ID`
    LEFT JOIN `eventGuest` ON `eventTicket`.`EVENT_ID` = `eventGuest`.`EVENT_ID`
    LEFT JOIN `eventSponsor` ON  `eventGuest`.`EVENT_ID` = `eventSponsor`.`EVENT_ID`

    WHERE `event`.`EVENT_ID` = 1
    GROUP BY `event`.`EVENT_ID`, `eventTicket`.`TICKET_ID`, `eventGuest`.`GUEST_ID`, `eventSponsor`.`SPONSOR_ID`    ;

这样返回一个结果集

eventId | eventName    | ticketId | type | guestId | guestName      | sponsorId       | sponsorName
   1    | firstEvent   | 1        | free | 1       |firstEventGuest | 1 | firstEventSponsor
   1    | firstEvent   | 2        | paid | 1       |firstEventGuest | 1 | firstEventSponsor

如果可能的话,我希望获得类似这样的结果集

eventId | eventName    | ticketId | type | guestId | guestName      | sponsorId       | sponsorName
   1    | firstEvent   | 1        | free | 1       |firstEventGuest | 1 | firstEventSponsor
   1    | firstEvent   | 2        | paid | NULL       |NULL       | NULL  | NULL

我是我使用了错误的方法还是默认方法,请帮助我解决这个挑战/

【问题讨论】:

  • 第二行你的票号是2但是类型是付费的?
  • 是的,这是正确的,但表示来宾 ID 和赞助商 ID,我认为这可能是默认行为。如果有任何解决方法?
  • 你的客人表应该有票证,以确定客人有哪张票。
  • 客人与活动相关,而非门票。他们是出席活动的特邀嘉宾
  • 那么您的客人 ID 1 将始终链接到工单 ID 1 和 3,因为它们与事件 ID 1 相关联。客人表中的所有记录是否总是免费的(工单 ID 1),除非它是事件 ID 2(票证 ID 2)?

标签: mysql sql join left-join


【解决方案1】:

这将适用于您的示例数据。

SELECT e.event_id AS 'eventId',
       e.name AS 'eventName',
       t.ticket_id AS 'ticketId',
       t.type AS 'ticketType',
       g.guest_id AS 'guestId',
       CONCAT(g.first_name, " ", g.last_name) AS 'guestName', 
       s.sponsor_id AS 'sponsorId',
       s.name AS 'sponsorName'
  FROM t_event e
  LEFT OUTER JOIN t_ticket t 
    ON e.event_id = t.event_id
  LEFT OUTER JOIN (SELECT *, CASE WHEN event_id = 1 THEN 1 ELSE event_id END ticket_id FROM t_guest) g 
    ON t.event_id = g.event_id AND t.ticket_id = g.ticket_id
  LEFT OUTER JOIN t_sponsor s 
    ON g.event_id = s.event_id
 WHERE e.event_id = 1
 GROUP BY e.event_id, t.ticket_id, g.guest_id, s.sponsor_id;

结果(我添加了 guest id 3 示例数据)

eventId eventName   ticketId ticketType  guestId guestName         sponsorId sponsorName
1       firstEvent  1        free        1       firstEvent guest  1         firstEventSponsor
1       firstEvent  1        free        3       thirdEvent guest  1         firstEventSponsor
1       firstEvent  3        paid        NULL    NULL              NULL      NULL
2       secondEvent 2        secondEvent 2       secondEvent guest 2         secondEventSponsor

【讨论】:

  • 对不起,但他们仍然为事件 id 1 出票 1 和赞助商 1。我想要的是在重复值的地方为空。我认为这是一个死胡同
  • 正如我所说,我添加了与事件 id 1 相关联的 guest id 3 示例数据。尝试查询您的数据库并查看结果。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-11-02
  • 1970-01-01
  • 2021-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多