SQL Server 2008 R2:同一列上的多个条件与运算符
SQL Server 2008 R2: Multiple condition on same column with AND operator
Table:
CREATE TABLE EMPDetails
(
ID int,
EmpName varchar(20),
ColumnName varchar(20),
ColumnValue varchar(20)
);
记录:
INSERT INTO EMPDetails Values(1,'S','Company','Microsoft');
INSERT INTO EMPDetails Values(1,'S','Profession','Database');
INSERT INTO EMPDetails Values(1,'S','Location','USA');
INSERT INTO EMPDetails Values(1,'S','Company','Unisys');
INSERT INTO EMPDetails Values(1,'S','Company','TATA');
INSERT INTO EMPDetails Values(2,'U','Company','Microsoft');
INSERT INTO EMPDetails Values(2,'U','Profession','Software');
INSERT INTO EMPDetails Values(2,'U','Location','UK');
INSERT INTO EMPDetails Values(2,'U','Company','DXC');
INSERT INTO EMPDetails Values(2,'U','Company','AOL');
INSERT INTO EMPDetails Values(3,'R','Company','Microsoft');
INSERT INTO EMPDetails Values(3,'R','Profession','Software');
INSERT INTO EMPDetails Values(3,'R','Location','UK');
INSERT INTO EMPDetails Values(3,'R','Company','AOL');
我的尝试:
SELECT * FROM EMPDetails
WHERE (ColumnName = 'Company' AND ColumnValue = 'Microsoft') AND
(ColumnName = 'Profession' AND ColumnValue = 'Software')
预期输出
--------------------------------------------
ID EmpName ColumnName ColumnValue
--------------------------------------------
2 U Company Microsoft
2 U Profession Software
3 R Company Microsoft
3 R Profession Software
一种解决方案是使用 OR
和 EXISTS
SELECT * FROM EMPDetails e1
WHERE (ColumnName = 'Company' AND
ColumnValue = 'Microsoft' AND
EXISTS(SELECT * FROM EMPDetails e2
WHERE ColumnName = 'Profession' AND
ColumnValue = 'Software' AND
e1.id = e2.id)
) OR
(ColumnName = 'Profession' AND
ColumnValue = 'Software' AND
EXISTS(SELECT * FROM EMPDetails
WHERE ColumnName = 'Company' AND
ColumnValue = 'Microsoft' AND
e1.id = e2.id)))
在关系数据库中,一列(即 ColumnName
)不可能在一行中有两个不同的值,因此,您的结果始终为空。
您需要根据您的条件数计算它出现的次数,并将结果加入 table 本身。
SELECT a.*
FROM EMPDetails a
INNER JOIN
(
SELECT ID, EmpName
FROM EMPDetails
WHERE (ColumnName = 'Company' AND ColumnValue = 'Microsoft') OR
(ColumnName = 'Profession' AND ColumnValue = 'Software')
GROUP BY ID, EmpName
HAVING COUNT(*) = 2
) b ON a.ID = b.ID
AND a.EmpName = b.EmpName
WHERE (a.ColumnName = 'Company' AND a.ColumnValue = 'Microsoft') OR
(a.ColumnName = 'Profession' AND a.ColumnValue = 'Software')
这是一个Demo。
使用 INTERSECT
查找具有两种所需组合的 ID:
SELECT * FROM EMPDetails
WHERE ((ColumnName = 'Company' AND ColumnValue = 'Microsoft') OR
(ColumnName = 'Profession' AND ColumnValue = 'Software')) AND
ID IN (select id from EMPDetails
WHERE (ColumnName = 'Company' AND ColumnValue = 'Microsoft')
INTERSECT
select id from EMPDetails
WHERE (ColumnName = 'Profession' AND ColumnValue = 'Software'))
另一种方法
select
ID, EmpName, ColumnName, ColumnValue
from (
SELECT
*, total = sum(cnt) over (partition by ID, EmpName)
FROM
EMPDetails
cross apply (
select cnt = case
when ColumnName = 'Company' and ColumnValue = 'Microsoft' then 1
when ColumnName = 'Profession' and ColumnValue = 'Software' then 10
else 0
end) q
) t
where
cnt > 0
and total / 10 > 0
and total % 10 > 0
另一个但与其他相似
SELECT a.*
FROM EMPDetails a
JOIN ( SELECT ID
FROM EMPDetails
WHERE ColumnName = 'Company' AND ColumnValue = 'Microsoft'
intersect
SELECT ID
FROM EMPDetails
WHERE ColumnName = 'Profession' AND ColumnValue = 'Software'
) b
ON a.ID = b.ID
where (ColumnName = 'Company' AND ColumnValue = 'Microsoft')
OR (ColumnName = 'Profession' AND ColumnValue = 'Software')
Table:
CREATE TABLE EMPDetails
(
ID int,
EmpName varchar(20),
ColumnName varchar(20),
ColumnValue varchar(20)
);
记录:
INSERT INTO EMPDetails Values(1,'S','Company','Microsoft');
INSERT INTO EMPDetails Values(1,'S','Profession','Database');
INSERT INTO EMPDetails Values(1,'S','Location','USA');
INSERT INTO EMPDetails Values(1,'S','Company','Unisys');
INSERT INTO EMPDetails Values(1,'S','Company','TATA');
INSERT INTO EMPDetails Values(2,'U','Company','Microsoft');
INSERT INTO EMPDetails Values(2,'U','Profession','Software');
INSERT INTO EMPDetails Values(2,'U','Location','UK');
INSERT INTO EMPDetails Values(2,'U','Company','DXC');
INSERT INTO EMPDetails Values(2,'U','Company','AOL');
INSERT INTO EMPDetails Values(3,'R','Company','Microsoft');
INSERT INTO EMPDetails Values(3,'R','Profession','Software');
INSERT INTO EMPDetails Values(3,'R','Location','UK');
INSERT INTO EMPDetails Values(3,'R','Company','AOL');
我的尝试:
SELECT * FROM EMPDetails
WHERE (ColumnName = 'Company' AND ColumnValue = 'Microsoft') AND
(ColumnName = 'Profession' AND ColumnValue = 'Software')
预期输出
--------------------------------------------
ID EmpName ColumnName ColumnValue
--------------------------------------------
2 U Company Microsoft
2 U Profession Software
3 R Company Microsoft
3 R Profession Software
一种解决方案是使用 OR
和 EXISTS
SELECT * FROM EMPDetails e1
WHERE (ColumnName = 'Company' AND
ColumnValue = 'Microsoft' AND
EXISTS(SELECT * FROM EMPDetails e2
WHERE ColumnName = 'Profession' AND
ColumnValue = 'Software' AND
e1.id = e2.id)
) OR
(ColumnName = 'Profession' AND
ColumnValue = 'Software' AND
EXISTS(SELECT * FROM EMPDetails
WHERE ColumnName = 'Company' AND
ColumnValue = 'Microsoft' AND
e1.id = e2.id)))
在关系数据库中,一列(即 ColumnName
)不可能在一行中有两个不同的值,因此,您的结果始终为空。
您需要根据您的条件数计算它出现的次数,并将结果加入 table 本身。
SELECT a.*
FROM EMPDetails a
INNER JOIN
(
SELECT ID, EmpName
FROM EMPDetails
WHERE (ColumnName = 'Company' AND ColumnValue = 'Microsoft') OR
(ColumnName = 'Profession' AND ColumnValue = 'Software')
GROUP BY ID, EmpName
HAVING COUNT(*) = 2
) b ON a.ID = b.ID
AND a.EmpName = b.EmpName
WHERE (a.ColumnName = 'Company' AND a.ColumnValue = 'Microsoft') OR
(a.ColumnName = 'Profession' AND a.ColumnValue = 'Software')
这是一个Demo。
使用 INTERSECT
查找具有两种所需组合的 ID:
SELECT * FROM EMPDetails
WHERE ((ColumnName = 'Company' AND ColumnValue = 'Microsoft') OR
(ColumnName = 'Profession' AND ColumnValue = 'Software')) AND
ID IN (select id from EMPDetails
WHERE (ColumnName = 'Company' AND ColumnValue = 'Microsoft')
INTERSECT
select id from EMPDetails
WHERE (ColumnName = 'Profession' AND ColumnValue = 'Software'))
另一种方法
select
ID, EmpName, ColumnName, ColumnValue
from (
SELECT
*, total = sum(cnt) over (partition by ID, EmpName)
FROM
EMPDetails
cross apply (
select cnt = case
when ColumnName = 'Company' and ColumnValue = 'Microsoft' then 1
when ColumnName = 'Profession' and ColumnValue = 'Software' then 10
else 0
end) q
) t
where
cnt > 0
and total / 10 > 0
and total % 10 > 0
另一个但与其他相似
SELECT a.*
FROM EMPDetails a
JOIN ( SELECT ID
FROM EMPDetails
WHERE ColumnName = 'Company' AND ColumnValue = 'Microsoft'
intersect
SELECT ID
FROM EMPDetails
WHERE ColumnName = 'Profession' AND ColumnValue = 'Software'
) b
ON a.ID = b.ID
where (ColumnName = 'Company' AND ColumnValue = 'Microsoft')
OR (ColumnName = 'Profession' AND ColumnValue = 'Software')