有表格:
用户
id | login | password | creationDate
_____________________________________
1 | user1 | 123 | 12.12.12
2 | user2 | 123 | 12.12.12
3 | user3 | 123 | 12.12.12
AdditionalParams
id | userId | name | value
_______________________________
1 | 1 | petName | jim
2 | 1 | houseNum| 2
3 | 1 | favTea | black
4 | 2 | favTea | black
5 | 2 | petName | jam
6 | 3 | favTea | green
7 | 3 | lang | C++
8 | 3 | petName | jem
所以,它包含差异。 diff的数据。用户,而不是所有用户都拥有相同数量的额外婴儿车;
我的目标是选择类似"选择所有用户名为petNames的用户,但仅限于favTea = black":
结果
User.id | User.login | User.password | petName
_____________________________________________
1 | user1 | 123 | jim
2 | user2 | 123 | jam
我已经尝试了很多变体,但是没有它们会返回我想要的东西。 这是我的尝试:
WITH Results_CTE AS
(
SELECT DISTINCT AdditionalParams.value,
User.id as 'id',
User.login as 'login',
User.password as 'password',
User.creationDate as 'creationDate',
AdditionalParams.value as 'pet'
FROM User
INNER JOIN AdditionalParams
ON User.id = AdditionalParams.userId
WHERE AdditionalParams.name = 'PetName' AND
AdditionalParams.value = 'black' AND
AdditionalParams.name = 'PetName' OR AdditionalParams.name = 'favTea'
)
SELECT
id as 'id',
login as 'login',
password as 'password',
status as 'status',
batchType as 'batchType',
creationDate as 'creationDate',
ExportDate as 'ExportDate',
pet as 'pet'
FROM Results_CTE
PS:DataBase是MS SQL Server 2008
答案 0 :(得分:2)
您可以使用:
SELECT u.id, u.login, u.password, ap2.value AS petName
FROM User AS u
INNER JOIN AdditionalParams AS ap
ON u.Id = ap.userId AND ap.name = 'favTea' AND ap.value = 'black'
LEFT JOIN AdditionalParams AS ap2 ON u.Id = ap2.userId AND ap2.name = 'petName'
它只是一个包含两个JOIN
操作的查询。 ON
条款的谓词实现了'业务'逻辑。
答案 1 :(得分:0)
只是在黑暗中拍摄,但我认为你可以用这么简单的东西替换你的整个查询。请注意,以明文形式存储密码是可怕的。密码应始终加盐和散列。原始值不应该是可恢复的。如果有人没有宠物,我也会将AdditionalParams加入左连接。
SELECT DISTINCT
User.id
, User.login
, User.password
, User.creationDate
, AdditionalParams.value as 'pet'
FROM User u
LEFT JOIN AdditionalParams ap ON u.id = ap.userId
WHERE ap.name = 'PetName'
答案 2 :(得分:0)
1)用inner
left
可能更好
select u.*, p.value as petname
from users u
inner join AdditionalParams p on p.userid = u.id and p.Name= 'petName'
where exists(
select 1 from AdditionalParams pp
where pp.userid = u.id and pp.Name= 'favTea' and pp.value = 'black')
2)使用inner join
代替exists
3)转轴
;with Users as
(
select 1 as id, 'user1' as userlogin
union all
select 2, 'user2'
union all
select 3, 'user3'
),
AdditionalParams as
(
select 1 as id, 1 as userid, cast('petName' as varchar(100)) as name, cast('jim' as varchar(100)) as value
union all
select 2, 1, 'houseNum', '2'
union all
select 3, 1, 'favTea', 'black'
union all
select 4, 2, 'favTea', 'black'
union all
select 5, 2, 'houseNum', '2'
union all
select 6, 3, 'favTea', 'green'
union all
select 7, 3, 'lang', 'C++'
union all
select 8, 3, 'petName', 'jem'
),
PivotedParams as
(
select p.*
from
(
select p.userid, u.userlogin, p.name as paramname, p.value
from Users u
inner join AdditionalParams p on p.userid = u.id
) up
PIVOT (MAX(up.Value) FOR paramname in ([petName], [favtea])) p
)
select *
from PivotedParams p
where p.favtea = 'black'
答案 3 :(得分:0)
您可以尝试使用Pivot。如果“附加参数”表中的名称列是动态的,则可以尝试使用动态数据透视表。
SELECT U.id, U.login, U.password, T.Petname
FROM
(
SELECT userid, name, value
from AdditionalParams
) AS T JOIN User AS U ON U.id = T.userid
PIVOT
(
MAX(value)
for name
IN([petName], [favTea], [lang], houseNum)
) as pivoting
where favTea = 'Black'