如何逐行为无结果子查询分配默认值?

时间:2016-12-14 23:46:15

标签: mysql

我有两个包含用户信息的表格和一个朋友'用户之间的关系。为避免要求标记为“不是朋友”的关系。在每个用户和每个其他用户之间,我选择在关系表中定义没有关系的用户,而不是朋友。

然而,现在我正在尝试实施搜索功能以帮助添加了人物作为他们的朋友的用户,我试图返回其名称与搜索名称匹配的其他用户的列表;我还试图输出搜索用户和结果用户之间的关系状态,并且我试图在没有关系时尝试使用IFNULL来设置返回值。

我编写的查询适用于单个用户,但是当子查询结果返回多个用户时,IFNULL语句不会逐行调用,而只是调用当整个结果表为空时。

以下是我的表格:

user_table
+----+------------+-----------+
| id | first_name | last_name |
+----+------------+-----------+
| 1  | John       | Doe       |
| 2  | Jane       | One       |
| 3  | Jane       | Two       |
| 4  | Jane       | Three     |
+----+------------+-----------+

relationship_table
+-----------+-------------+--------------+
| sender_id | receiver_id | relationship |
+-----------+-------------+--------------+
| 1         | 2           | friends      |
| 3         | 1           | pending      |
+-----------+-------------+--------------+

当用户John Doe执行搜索"jane"时,我尝试生成以下内容。

results
+----+------------+-----------+--------------+
| id | first_name | last_name | relationship |
+----+------------+-----------+--------------+
| 2  | Jane       | One       | friends      |
| 3  | Jane       | Two       | pending      |
| 4  | Jane       | Three     | not friends  |
+----+------------+-----------+--------------+

以下是我目前的查询:

SELECT user_table.id, user_table.first_name, user_table.last_name, derived_table.relationship
FROM user_table, (
    SELECT IFNULL((type), 'not friends') AS relationship
    FROM relationship_table
    WHERE sender_id IN (
        SELECT id
        FROM user_table
        WHERE first_name LIKE 'jane%'
        OR last_name LIKE 'jane%'
        AND id != '1'
    )
    AND receiver_id = '1'
    OR receiver_id IN (
        SELECT id
        FROM user_table
        WHERE first_name LIKE 'jane%'
        OR last_name LIKE 'jane%'
        AND id != '1'
    )
    AND sender_id = '1'
)derived_table
WHERE first_name LIKE 'jane%'
OR last_name LIKE 'jane%'
AND user_table.id != '1'

此查询目前会针对"jane"

的搜索返回此信息
+----+------------+-----------+--------------+
| id | first_name | last_name | relationship |
+----+------------+-----------+--------------+
| 2  | Jane       | One       | friends      |
| 2  | Jane       | One       | pending      |
| 3  | Jane       | Two       | friends      |
| 3  | Jane       | Two       | pending      |
| 4  | Jane       | Three     | friends      |
| 4  | Jane       | Three     | pending      |
+----+------------+-----------+--------------+

对我而言,显而易见的原因是因为关系子查询的整个结果被添加到每组用户数据中,而不是与相应的用户匹配。

逻辑告诉我,使用id的联接可以解决这个问题,尽管由于用户之间没有发送友情请求之间的一致性,因此没有一致的ID加入...我不知道如何正确加入它们。

P.S。我确信可能有一种方法可以检查您作为发件人或收件人的关系,以便更好地提供帮助。

1 个答案:

答案 0 :(得分:0)

在所有简氏的桌子和约翰的所有朋友的桌子之间左联接。

所有简氏:

**Query**
SELECT user_table.id, user_table.first_name, user_table.last_name
FROM user_table
WHERE first_name LIKE 'jane%'
OR last_name LIKE 'jane%'
AND id != '1'

**Results**
+----+------------+-----------+
| id | first_name | last_name |
+----+------------+-----------+
|  2 | Jane       | One       |
|  3 | Jane       | Two       |
|  4 | Jane       | Three     |
+----+------------+-----------+

John的朋友们:

**Query**
(
    SELECT relationship_table.sender_id AS id, relationship
    FROM relationship_table
    WHERE receiver_id = '1'
)
UNION
(
    SELECT relationship_table.receiver_id AS id, relationship
    FROM relationship_table
    WHERE sender_id = '1'
)

**Results**
+----+--------------+
| id | relationship |
+----+--------------+
|  2 | friends      |
|  3 | pending      |
+----+--------------+

然后合并:

**Query**
SELECT searched_users.id, searched_users.first_name, searched_users.last_name, IFNULL(users_friends.relationship, 'not friends') AS relationship
FROM (
    SELECT user_table.id, user_table.first_name, user_table.last_name
    FROM user_table
    WHERE first_name LIKE 'jane%'
    OR last_name LIKE 'jane%'
    AND id != '1'
)searched_users
LEFT JOIN (
    (
        SELECT relationship_table.sender_id AS id, relationship
        FROM relationship_table
        WHERE receiver_id = '1'
    )
    UNION
    (
        SELECT relationship_table.receiver_id AS id, relationship
        FROM relationship_table
        WHERE sender_id = '1'
    )
)users_friends
ON searched_users.id = users_friends.id

**Results**
+----+------------+-----------+--------------+
| id | first_name | last_name | relationship |
+----+------------+-----------+--------------+
| 2  | Jane       | One       | friends      |
| 3  | Jane       | Two       | pending      |
| 4  | Jane       | Three     | not friends  |
+----+------------+-----------+--------------+
相关问题