我有一个像这样的USERS表
USERS
user_id | username
1 tom
2 sam
Run Code Online (Sandbox Code Playgroud)
我也有这样的USER_META表
USER_META
user_meta_id | user_id | meta_key | meta_value
1 1 active 1
2 1 car dodge
3 2 active 0
4 2 car honda
Run Code Online (Sandbox Code Playgroud)
我的问题是我需要选择meta_keys active和car,但仅限于活动值为1的用户,所以我的结果集应该是这样的
user_id | user_name | user_meta_id | meta_key | meta_value
1 tom 1 active 1
1 tom 2 car dodge
Run Code Online (Sandbox Code Playgroud)
我尝试了一些东西,但我不能得到这种类型的结果集.这是我认为可行的
SELECT * FROM USERS
LEFT JOIN USER_META
ON USERS."user_id" = USER_META
AND (USER_META."meta_key" = 'active' OR USER_META."meta_key" = 'car')
WHERE (USER_META."meta_key" = 'active'
AND USER_META."meta_value" = 1)
Run Code Online (Sandbox Code Playgroud)
这个问题是我得到一个缺少汽车meta_key/meta_value的结果集
user_id | user_name | user_meta_id | meta_key | meta_value
1 tom 1 active 1
Run Code Online (Sandbox Code Playgroud)
如何修改查询以获取所有元信息?谢谢.
首先,这种实体 - 属性 - 值数据模型通常是一个非常糟糕的想法.您基本上重新实现了关系数据库为您提供的开箱即用的功能,并且查询很快就变得非常笨拙.通常,您需要在USER_META表中加入N次,以便将N个属性作为列或者为了对数据设置N个谓词.
在数据建模方面,如果您避免创建区分大小写的列名,那么未来的开发人员通常会感激不尽,因此他们不必每次都对每个标识符进行双引号.
由于你需要两个键,你应该可以做这样的事情(我假设它meta_value总是存储为一个字符串,即使它代表一个数字或布尔值)
SELECT usr."user_id",
usr."user_name",
meta."user_meta_id",
meta."meta_key",
meta."meta_value"
FROM users usr
JOIN user_meta meta ON (usr."user_id" = meta."user_id")
WHERE meta."meta_key" in ('active', 'car')
AND usr."user_id" IN (SELECT active."user_id"
FROM user_meta active
WHERE active."meta_key" = 'active'
AND active."meta_value" = '1' )
Run Code Online (Sandbox Code Playgroud)
它返回您发布的数据的预期结果
SQL> ed
Wrote file afiedt.buf
1 with users as (
2 select 1 "user_id", 'tom' "user_name" from dual union all
3 select 2, 'sam' from dual
4 ),
5 user_meta as (
6 select 1 "user_meta_id",
7 1 "user_id",
8 'active' "meta_key",
9 '1' "meta_value" from dual union all
10 select 2, 1, 'car', 'dodge' from dual union all
11 select 3, 2, 'active', '0' from dual union all
12 select 4, 2, 'car', 'honda' from dual
13 )
14 SELECT usr."user_id",
15 usr."user_name",
16 meta."user_meta_id",
17 meta."meta_key",
18 meta."meta_value"
19 FROM users usr
20 JOIN user_meta meta ON (usr."user_id" = meta."user_id")
21 WHERE meta."meta_key" in ('active', 'car')
22 AND usr."user_id" IN (SELECT active."user_id"
23 FROM user_meta active
24 WHERE active."meta_key" = 'active'
25* AND active."meta_value" = '1' )
SQL> /
user_id use user_meta_id meta_k meta_
---------- --- ------------ ------ -----
1 tom 1 active 1
1 tom 2 car dodge
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
25057 次 |
| 最近记录: |