简体   繁体   English

您如何显示来自mysql表中多个条目的数据,这些条目通过单个值匹配与另一个联接?

[英]How do you display data from multiple entries in a mysql table that are JOINED with another via a single value match?

I need to select and display information from a pair of MySQL tables but the syntax eludes me. 我需要从一对MySQL表中选择并显示信息,但是语法使我难以理解。 Specifically, I need to JOIN the data from the cwd_user table with the data from the cwd_user_attribute table on the field cwd_user.id == cwd_user_attribute.user_id, but I also need to display values from several entries in the cwd_user_attribute table in a single line. 具体来说,我需要将cwd_user表中的数据与字段cwd_user.id == cwd_user_attribute.user_id上cwd_user_attribute表中的数据进行联接,但是我还需要在一行中显示cwd_user_attribute表中多个条目的值。 It's the latter that eludes me. 是后者使我难以理解。 Here are the gory details: 这是血腥的细节:

Given two tables: 给定两个表:

mysql (crowd@prod:crowddb)> desc cwd_user;
+---------------------+--------------+------+-----+---------+-------+
| Field               | Type         | Null | Key | Default | Extra |
+---------------------+--------------+------+-----+---------+-------+
| id                  | bigint(20)   | NO   | PRI | NULL    |       |
| user_name           | varchar(255) | NO   |     | NULL    |       |
| active              | char(1)      | NO   | MUL | NULL    |       |
| created_date        | datetime     | NO   |     | NULL    |       |
| updated_date        | datetime     | NO   |     | NULL    |       |
| display_name        | varchar(255) | YES  |     | NULL    |       |
| directory_id        | bigint(20)   | NO   | MUL | NULL    |       |
+---------------------+--------------+------+-----+---------+-------+


mysql (crowd@prod:crowddb)> desc cwd_user_attribute;
+-----------------------+--------------+------+-----+---------+-------+
| Field                 | Type         | Null | Key | Default | Extra |
+-----------------------+--------------+------+-----+---------+-------+
| id                    | bigint(20)   | NO   | PRI | NULL    |       |
| user_id               | bigint(20)   | NO   | MUL | NULL    |       |
| directory_id          | bigint(20)   | NO   | MUL | NULL    |       |
| attribute_name        | varchar(255) | NO   |     | NULL    |       |
| attribute_value       | varchar(255) | YES  |     | NULL    |       |
+-----------------------+--------------+------+-----+---------+-------+

Assume that there are up to seven possible values for cwd_user_attribute.attribute_name and I'm interested in four of them: lastAuthenticated, Team, Manager Notes. 假设cwd_user_attribute.attribute_name最多有七个值,我对其中四个感兴趣:lastAuthenticated,Team,Manager Notes。 Example: 例:

mysql (crowd@prod:crowddb)> select * from cwd_user_attribute where user_id = (select id from cwd_user where user_name = 'gspinrad');
+---------+---------+--------------+-------------------------+----------------------------------+
| id      | user_id | directory_id | attribute_name          | attribute_value                  |
+---------+---------+--------------+-------------------------+----------------------------------+
|   65788 |   32844 |            1 | invalidPasswordAttempts | 0                                | 
|   65787 |   32844 |            1 | lastAuthenticated       | 1473360428804                    |  
|   65790 |   32844 |            1 | passwordLastChanged     | 1374005378040                    | 
|   65789 |   32844 |            1 | requiresPasswordChange  | false                            | 
| 4292909 |   32844 |            1 | Team                    | Engineering - DevOps             | 
| 4292910 |   32844 |            1 | Manager                 | Matt Karaffa                     |  
| 4292911 |   32844 |            1 | Notes                   | Desk 32:2:11                     | 
+---------+---------+--------------+-------------------------+----------------------------------+
5 rows in set (0.00 sec)

I can get a list of the users sorted by lastAuthenticated with this query: 我可以通过此查询获取按lastAuthenticated排序的用户列表:

SELECT cwd_user.user_name, cwd_user.id, cwd_user.display_name, from_unixtime(cwd_user_attribute.attribute_value/1000) as last_login FROM cwd_user JOIN cwd_directory ON cwd_user.directory_id = cwd_directory.id JOIN cwd_user_attribute ON cwd_user.id = cwd_user_attribute.user_id AND cwd_user_attribute.attribute_name='lastAuthenticated' WHERE DATEDIFF((NOW()), (from_unixtime(cwd_user_attribute.attribute_value/1000))) > 90 and cwd_user.active='T' order by last_login limit 4;

Result: 结果:

+-----------------------+---------+-----------------------+---------------------+
| user_name             | id      | display_name          | last_login |
+-----------------------+---------+-----------------------+---------------------+
| jenkins-administrator | 1605636 | Jenkins Administrator | 2011-10-27 17:28:05 |
| sonar-administrator   | 1605635 | Sonar Administrator   | 2012-02-06 15:59:59 |
| jfelix                | 1605690 | Joey Felix            | 2012-02-06 19:15:15 |
| kbitters              | 3178497 | Kitty Bitters         | 2013-09-03 10:09:59 |

What I need to add to the output is the value of cwd_user_attribute.attribute_value where cwd_user_attribute.attribute_name is Team, Manager, and/or Notes. 我需要添加到输出中的是cwd_user_attribute.attribute_value的值,其中cwd_user_attribute.attribute_name是团队,经理和/或Notes。 The output would look something like this: 输出看起来像这样:

+-----------------------+---------+-----------------------+-------------------------------------------------------------------+
| user_name             | id      | display_name          | last_login          | Team          | Manager      |  Notes       |
+-----------------------+---------+-----------------------+-------------------------------------------------------------------+
| jenkins-administrator | 1605636 | Jenkins Administrator | 2011-10-27 17:28:05 | Internal      | Internal     |              | 
| sonar-administrator   | 1605635 | Sonar Administrator   | 2012-02-06 15:59:59 | Internal      | Internal     |              |
| jfelix                | 1605690 | Joey Felix            | 2012-02-06 19:15:15 | Hardware Eng. | Gary Spinrad | Desk 32:1:51 |
| kbitters              | 3178497 | Kitty Bitters         | 2013-09-03 10:09:59 | Software QA   | Matt Karaffa | Desk 32:2:01 |
+-----------------------+---------+-----------------------+-------------------------------------------------------------------+

You can achieve that result with an additional LEFT JOIN with the attribute table. 您可以使用带有属性表的附加LEFT JOIN来实现该结果。 Then use GROUP BY and aggregated CASE statements to pivot the result (rows to columns). 然后使用GROUP BY和聚合的CASE语句来旋转结果(行到列)。

SELECT
    cwd_user.user_name,
    cwd_user.id,
    cwd_user.display_name,
    from_unixtime(cwd_user_attribute.attribute_value/1000) as last_login,
    MIN(CASE WHEN attr2.attribute_name = 'TEAM'    THEN attr2.attribute_value END) as Team,
    MIN(CASE WHEN attr2.attribute_name = 'Manager' THEN attr2.attribute_value END) as Manager,
    MIN(CASE WHEN attr2.attribute_name = 'Notes'   THEN attr2.attribute_value END) as Notes
FROM 
    cwd_user 
JOIN 
    cwd_user_attribute ON cwd_user.id = cwd_user_attribute.user_id
                       AND cwd_user_attribute.attribute_name='lastAuthenticated'
LEFT JOIN 
    cwd_user_attribute attr2 ON  cwd_user.id = attr2.user_id
                             AND attr2.attribute_name IN ('Team', 'Manager', 'Notes')
WHERE 
    DATEDIFF((NOW()), (from_unixtime(cwd_user_attribute.attribute_value/1000))) > 90
    AND cwd_user.active = 'T'
GROUP BY 
    cwd_user.id
ORDER BY 
    last_login 
LIMIT 4

With strict mode you would need to list all not aggregated columns in the GROUP BY clause 使用严格模式时,您需要在GROUP BY子句中列出所有未聚合的列

GROUP BY 
    cwd_user.user_name,
    cwd_user.id,
    cwd_user.display_name,
    cwd_user_attribute.attribute_value

Another way is just to use three LEFT JOINs (one join per attribute name): 另一种方法是只使用三个LEFT JOIN(每个属性名称一个联接):

SELECT
    cwd_user.user_name,
    cwd_user.id,
    cwd_user.display_name,
    from_unixtime(cwd_user_attribute.attribute_value/1000) as last_login,
    attr_team.attribute_value as Team,
    attr_manager.attribute_value as Manager,
    attr_notes.attribute_value as Notes
FROM cwd_user 
JOIN cwd_user_attribute
  ON  cwd_user.id = cwd_user_attribute.user_id
  AND cwd_user_attribute.attribute_name='lastAuthenticated'
LEFT JOIN cwd_user_attribute attr_team
  ON  cwd_user.id = attr2.user_id
  AND attr2.attribute_name = 'Team'
LEFT JOIN cwd_user_attribute attr_manager
  ON  cwd_user.id = attr2.user_id
  AND attr2.attribute_name = 'Manager'
LEFT JOIN cwd_user_attribute attr_notes
  ON  cwd_user.id = attr2.user_id
  AND attr2.attribute_name = 'Notes'
WHERE DATEDIFF((NOW()), (from_unixtime(cwd_user_attribute.attribute_value/1000))) > 90
  and cwd_user.active='T'
order by last_login limit 4

Note: I have removed the join with directory table because you seem not to use it. 注意:因为您似乎不使用它,所以我删除了带目录表的联接。 Add it again, if you need it for filtering. 如果需要进行过滤,请再次添加。

Note 2: Some attributes that you often use for a search (like lastAuthenticated ) should be converted to indexed columns in the users table to improve the search performance. 注意2:应将您经常用于搜索的某些属性(如lastAuthenticated )转换为users表中的索引列,以提高搜索性能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 当相关记录在MySQL中包含给定值时,如何从联接表中提取所有数据? - How do you pull all data from a joined table when a related record contains a given value in MySQL? 如何从mysql中的联接表中查找单行数据? - How to find single row data from joined table in mysql? MySQL:查询已加入日期列表,但是如何在每个日期显示多个条目 - MySQL: query joined to list of dates, but how do I display multiple entries per date 你如何更新mysql中另一个表的多个字段? - How do you update multiple fields from another table in mysql? mysql-如果表中有多个具有相同值的条目,如何显示所有最大值? - mysql - How do I display all of the biggest values, if there are multiple entries in the table with the same value? 如何将数据库中两个表的连接条目显示为HTML表? - How to display joined entries from two tables in a database as an HTML table? 你如何在 MYSQL 中将三个连接的表多次连接到第四个表 - How do you do multiple joins three joined tables to a fourth table in MYSQL MySQL使用连接表中的值更新单个表上的查询 - MySQL update query on a single table with value from joined table 从具有多个条目的另一个表更新MYSQL - MYSQL update from another table with multiple entries 你如何从PHP的MySQL中匹配一个单引号的字符串 - How do you match a string with single quote in mysql from php
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM