简体   繁体   中英

MySQL View issue - how join tables in this case?

I am puzzling a problem in my MySQL learning project, and the concept on JOIN still keeps on being an issue for me, so any advise is appreciated. I have 4 interrelated tables and am trying to create a view. My tables are:

  • USERS

      CREATE TABLE `users` ( `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, `name` VARCHAR(100) NOT NULL, `last_name` VARCHAR(100) NOT NULL, `email` VARCHAR(30) NOT NULL, `address` VARCHAR(100) NOT NULL, `phone` VARCHAR(50) NOT NULL, `year_of_birth` INT(4) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; 
  • BOOKS

      CREATE TABLE `books` ( `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, `title` VARCHAR(100) NOT NULL, `condition` ENUM('mint', 'new', 'medium', 'poor', 'needs replacement'), `date_added` DATE ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; 
  • USER_ORDERS

      CREATE TABLE `user_orders` ( `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, `user_id` INT(11) UNSIGNED NULL, `start_date` DATETIME DEFAULT CURRENT_TIMESTAMP, `due_date` DATE NULL, CONSTRAINT `fk10_orders_books` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON UPDATE CASCADE ON DELETE SET NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; 
  • BOOKS_ORDERS

      CREATE TABLE `books_orders` ( `order_id` INT(11) UNSIGNED NOT NULL, `book_id` INT(11) UNSIGNED NOT NULL, PRIMARY KEY (`order_id`, `book_id`), CONSTRAINT `fk_orders_user_orders` FOREIGN KEY (`order_id`) REFERENCES `user_orders` (`order_id`) ON UPDATE CASCADE ON DELETE CASCADE, CONSTRAINT `fk_orders_books` FOREIGN KEY (`book_id`) REFERENCES `books` (`id`) ON UPDATE CASCADE ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; 

What I am trying to do is to create a view, that would show concatenated user's first and last name, id of the order and the books themselves. What I did:

          CREATE SQL SECURITY INVOKER VIEW userBooksAndOrders AS 
            SELECT CONCAT(users.first_name, ' ', users.last_name) AS user_name, user_orders.order_id, books.title 
            FROM user_orders, users, books, books_orders
            WHERE user_orders.user_id = users.id AND books_orders.book_id = books.id;

And it looks that the result I am getting after this query are not really relevant. However, I can't find the mistake in the statement, what am I missing? Thanks in advance!

USERS -- seems ok but when you were creating view you used first_name but there is no first name so you have to use name in your view

 CREATE TABLE `users` (
          `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
          `name` VARCHAR(100) NOT NULL,
          `last_name` VARCHAR(100) NOT NULL,
          `email` VARCHAR(30) NOT NULL,
          `address` VARCHAR(100) NOT NULL,
          `phone` VARCHAR(50) NOT NULL,
          `year_of_birth` INT(4) NOT NULL
        ) ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

BOOKS -- table is fine you don't have to change here

CREATE TABLE `books` (
          `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
          `title` VARCHAR(100) NOT NULL,
          `condition` ENUM('mint', 'new', 'medium', 'poor', 'needs replacement'),
          `date_added` DATE 
        ) ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

BOOKS_ORDERS -- there are some errors. First of all, order_id is missing which you intended to use in books_order table. I also created an index using order_id. Your start_date had some issue with a default value, fixed below

CREATE TABLE `user_orders` (
  `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
  `user_id` INT(11) UNSIGNED DEFAULT NULL,
  `book_id` INT(11) UNSIGNED DEFAULT NULL,
  `order_id` INT(11) UNSIGNED DEFAULT NULL,
  `start_date` TIMESTAMP NULL DEFAULT NULL,
  `due_date` DATE DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `fk9_orders_users` (`book_id`),
  KEY `fk10_orders_books` (`user_id`),
  KEY `fk11_orders_users` (`order_id`),
  CONSTRAINT `fk9_orders_users` FOREIGN KEY (`book_id`) REFERENCES `books` (`id`) ON DELETE SET NULL ON UPDATE CASCADE,
  CONSTRAINT `fk10_orders_books` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE SET NULL ON UPDATE CASCADE
) ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

BOOKS_ORDERS -- is fine no need to change here

     CREATE TABLE `books_orders` (
      `order_id` INT(11) UNSIGNED NOT NULL,
      `book_id` INT(11) UNSIGNED NOT NULL,
    PRIMARY KEY (`order_id`, `book_id`),

    CONSTRAINT `fk_orders_user_orders` FOREIGN KEY (`order_id`) REFERENCES `user_orders` (`order_id`) 
    ON UPDATE CASCADE ON DELETE CASCADE, 

    CONSTRAINT `fk_orders_books` FOREIGN KEY (`book_id`) REFERENCES `books` (`id`) 
    ON UPDATE CASCADE ON DELETE CASCADE
   ) ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

userBooksAndOrders -- your view will work now

  CREATE VIEW userBooksAndOrders AS 
    SELECT CONCAT(users.name, ' ', users.last_name) AS user_name, user_orders.order_id, books.title 
    FROM user_orders, users, books, books_orders
    WHERE user_orders.user_id = users.id AND books_orders.book_id = books.id;

you can check this link

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM