我有像这样的USERS表
用户
user_id | username
1 tom
2 sam
我也有像这样的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
我的问题是我需要选择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
我尝试过一些东西,但是我无法得到这种结果集。这是我认为可行的方法
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)
问题在于我得到的结果集缺少汽车meta_key / meta_value
user_id | user_name | user_meta_id | meta_key | meta_value
1 tom 1 active 1
如何修改查询以获取所有元信息?感谢。
答案 0 :(得分:9)
首先,这种实体 - 属性 - 值数据模型通常是一个非常糟糕的想法。您基本上重新实现了关系数据库为您提供的开箱即用的功能,并且查询很快就变得非常笨拙。通常,您需要加入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' )
返回您发布的数据的预期结果
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
答案 1 :(得分:3)
SELECT * FROM USERS
LEFT JOIN USER_META ON
(USERS."user_id" = USER_META.”user_id”
AND (USER_META."meta_key" in ('active', 'car')
WHERE USERS."user_id" IN (select USER_META."user_id" from USER_META
where USER_META."meta_key" = 'active'
AND USER_META."meta_value" = 1
)
答案 2 :(得分:0)
由于我没有要测试的Oracle实例,所以这是我的头脑,但是这些内容是:
SELECT T1.user_ID, T1.user_name, T2.user_meta_id, T2.meta_key, T2.meta_value
FROM USERS T1 JOIN USER_META T2 ON T1.user_id = T2.user_id
AND ((T2.meta_key = 'active' AND meta_value = 1) OR (T2.meta_key = 'car'))
答案 3 :(得分:0)
试试这个:
SELECT
um1.user_id, um1.user_name, um.user_meta_id,
um.meta_key, um.meta_value
FROM
USER_META um,
(
SELECT
um0.*, u0.user_name
FROM
USER_META um0, USERS u0
WHERE
u0.user_id = um0.user_id
and um0.meta_key = 'active'
and um0.meta_value= '1'
) um1
WHERE
um.meta_key in ('active','car')
and um.user_id = um1.user_id