我已经完成了一些工作,并且经常看到这样的数据库:
Column_Values
+------+--------------+--------------+
| id | field_id | label |
+------------------------------------+
| 1 | first_name | First Name +-----------------+
| 2 | last_name | Last Name +-----------------------+
| | | | | |
| | | | | |
| | | | | |
+------+--------------+--------------+ | |
| |
User Row | |
+-------+ | |
| id | | |
+-------+ | |
+-----------+ 9000 | | |
| | 10000 | | |
| | | | |
| | | | |
| | | | |
| +-------+ | |
| | |
| Mapping Table | |
| +------------+-------------+---------+ | |
| | User_Id | Field ID | Value | | |
| +------------------------------------+ | |
+-----------> 9000 | 1 | John <-----------------+ |
| 9000 | 2 | Doe <-----------------------+
+------------+-------------+---------+
该列的名称实际上存储在另一个表中,而不是实际有一个first_name
和一个last_name
的列。
如何选择用户,以便获得类似的信息?
+---------+-------------+-----------+
| User_ID | First Name | Last Name |
+-----------------------------------+
| 9000 | John | Doe |
| | | |
+---------+-------------+-----------+
还有这种数据库的名称吗?似乎背后的逻辑是拥有动态列,但是我认为可以通过计划内的停机时间来更新表来缓解此问题。
答案 0 :(得分:1)
条件聚合应该可以解决问题:
SELECT
u.id,
MAX(CASE WHEN cv.field_id = 'first_name' THEN m.value END) first_name,
MAX(CASE WHEN cv.field_id = 'last_name' THEN m.value END) last_name
FROM user u
INNER JOIN mapping m ON m.user_id = u.id
INNER JOIN Column_Values cv ON cv.id = m.field_id
GROUP BY u.id
注意:如果您只需要用户ID及其名字和姓氏,那么就不需要输入user
表。只是:
SELECT
m.user_id,
MAX(CASE WHEN cv.field_id = 'first_name' THEN m.value END) first_name,
MAX(CASE WHEN cv.field_id = 'last_name' THEN m.value END) last_name
FROM mapping m ON
INNER JOIN Column_Values cv ON cv.id = m.field_id
GROUP BY m.user_id
答案 1 :(得分:1)
尝试一下
select
User_ID,
max(FirstName) FirstName,
max(LastName) LastName
from
(
select
User_ID,
case when c.Field_Id= 'first_name' then Value end as FirstName,
case when c.Field_Id = 'last_name' then Value end as LastName
from Column_Values c
inner join MappingTable m
on c.Id = m.FieldId
) t
group by
User_ID