如何在MySql中加入2列?

时间:2014-07-22 15:22:02

标签: mysql sql database

我的代码中有以下表结构,我试图从users表中提取用户名和名称字段,但查询当前只提取from_user_id数据。如何修改这个以便我得到两个单独的列,列出to_user_id和from_user_id的用户名和名称?

SELECT f.id, from_user_id, to_user_id, STATUS, u.username, u.name
FROM friend f
left JOIN users u ON f.from_user_id = u.id
WHERE f.id IN(
SELECT source_id
FROM notification
WHERE user_id = 5 AND notification_read = 1)

用户表:

CREATE TABLE `users` (
    `id` BIGINT(20) NOT NULL AUTO_INCREMENT,
    `username` VARCHAR(60) NOT NULL,
    `password` VARCHAR(64) NOT NULL,
    `enabled` TINYINT(4) NOT NULL DEFAULT '1',
    `email` VARCHAR(100) NOT NULL,
    `name` VARCHAR(100) NOT NULL,
    `created_on` DATETIME NOT NULL,
    `role` VARCHAR(50) NULL DEFAULT 'ROLE_USER',
    PRIMARY KEY (`id`),
    UNIQUE INDEX `username` (`username`)
)

和朋友表:

CREATE TABLE `friend` (
    `id` BIGINT(20) NOT NULL AUTO_INCREMENT,
    `from_user_id` BIGINT(20) NOT NULL,
    `to_user_id` BIGINT(20) NOT NULL,
    `status` INT(2) NOT NULL,
    `requested_date` DATETIME NULL DEFAULT NULL,
    `accepted_date` DATETIME NULL DEFAULT NULL,
    PRIMARY KEY (`id`),
    INDEX `from_user_id` (`from_user_id`),
    INDEX `to_user_id` (`to_user_id`)
)

和通知表:

CREATE TABLE `notification` (
    `id` BIGINT(20) NOT NULL AUTO_INCREMENT,
    `user_id` BIGINT(20) NOT NULL,
    `activity_type` TINYINT(4) NOT NULL,
    `source_id` BIGINT(20) NOT NULL,
    `parent_id` BIGINT(20) NULL DEFAULT NULL,
    `parent_type` TINYINT(4) NULL DEFAULT NULL,
    `notification_read` TINYINT(4) NOT NULL DEFAULT '0',
    `created_on` DATETIME NOT NULL,
    PRIMARY KEY (`id`),
    INDEX `user_id` (`user_id`),
    INDEX `created_on` (`created_on`)
)

1 个答案:

答案 0 :(得分:1)

您需要对users执行两个联接 - 对于朋友关系的每一方都要加一个,并在这两个联接的SELECT列表中包含相应的列反对users

SELECT
  f.id,
  from_user_id,
  to_user_id,
  STATUS,
  -- uf is an alias for the "from" user
  -- You must alias the columns to distinguish them
  uf.username AS from_username,
  uf.name AS from_name,
  -- ut is an alias for the "to" user
  ut.username AS to_username,
  ut.name AS to_name
FROM 
  friend f
  -- Join first for the from user info
  LEFT JOIN users uf ON f.from_user_id = uf.id
  -- Join again for the to user info
  LEFT JOIN users ut ON f.to_user_id = ut.id
WHERE f.id IN(
  SELECT source_id
  FROM notification
  WHERE user_id = 5 AND notification_read = 1
)

进一步说明......您可以将INNER JOIN替换为notification而不是IN ()子查询,您可以获得更好的效果。

SELECT
  DISTINCT /* needed assuming multiple notification.source_id per f.id */
  f.id,
  from_user_id,
  to_user_id,
  STATUS,
  uf.username AS from_username,
  uf.name AS from_name,
  ut.username AS to_username,
  ut.name AS to_name
FROM 
  friend f
  LEFT JOIN users uf ON f.from_user_id = uf.id
  LEFT JOIN users ut ON f.to_user_id = ut.id
  -- Join notification instead of the IN () subquery
  INNER JOIN notification 
    ON f.id = notification.source_id
    AND notification.user_id = 5
    AND notification_read = 1