排除存在于另一个表上的某些行,但也排除某些值之间的行?

时间:2018-08-06 04:14:18

标签: sql sql-server

我有以下2张桌子:

表A

Process  Type   SC  TC
AS         D     2  I
AS         D     2  C
AS         D     3  C
AS         D     2  X
AS         D     5  S

表B

Process  Type   SC  TC Valid
AS         D     2  I   y
AS         D     2  C   y

是否可以在不对任何值进行硬编码的情况下排除“ AS D 3 C”行。或者在这种情况下如何重写表B?我想排除该行,因为它在表B上无效,而且还因为它属于“ C”的TC之下。表A中的最后一行是可以的,因为没有任何可用TC为“ S”的验证。

AS         D     2  I
AS         D     2  C
AS         D     2  X
AS         D     5  S

5 个答案:

答案 0 :(得分:0)

下面的查询将起作用。在第一个选择中,您将TableA与其中TC <> 'S'的TableB连接起来,因为在与TableB比较时未考虑这些行,而Second Select从您在TableA的TC = 'S'中获取所有这些行,因为您总是希望它们。

SELECT a.Process, a.Type, a.SC, a.TC 
FROM TableA AS a
JOIN TableB AS b
ON a.TC = b.TC AND a.SC = b.SC
WHERE a.TC <> 'S'
UNION ALL
SELECT a.Process, a.Type, a.SC, a.TC 
FROM TableA AS a
WHERE a.TC = 'S'

答案 1 :(得分:0)

假设表A的有效标准为

  1. TC在表B中不存在
  2. 表A的SC =表B,表B有效='y'

您可以应用并集来解决

DECLARE @A TABLE (
SC INT,
TC VARCHAR(1)
)

DECLARE @B TABLE (
SC INT,
TC VARCHAR(1),
VALID VARCHAR(1)
)

INSERT INTO @A SELECT 2,'I'
INSERT INTO @A SELECT 2,'C'
INSERT INTO @A SELECT 3,'C'
INSERT INTO @A SELECT 2,'X'
INSERT INTO @A SELECT 5,'S'
INSERT INTO @B SELECT 2,'I','Y'
INSERT INTO @B SELECT 2,'C','Y'

--QUERY
SELECT * FROM @A A LEFT OUTER JOIN @B B ON A.TC=B.TC AND B.VALID='Y'
WHERE A.SC = B.SC
UNION
SELECT * FROM @A A LEFT OUTER JOIN @B B ON A.TC=B.TC AND B.VALID='Y'
WHERE B.SC IS NULL 

--QUERY 2
SELECT TOP 1 * FROM (
SELECT A.* FROM @A A LEFT OUTER JOIN @B B ON A.TC=B.TC AND B.VALID='Y'
WHERE A.SC = B.SC
UNION
SELECT A.* FROM @A A LEFT OUTER JOIN @B B ON A.TC=B.TC AND B.VALID='Y'
WHERE B.SC IS NULL 
) AS V

答案 2 :(得分:0)

以下查询可能会为您提供帮助,而无需使用任何硬代码

contact=mixer.blend('contacts.Contact'),

查询输出

    select distinct A.* from  A inner join  B on A.Process=B.Process 
    and A.Type =B.Type and A.SC=B.SC
    union
    select * from 
    (
    select distinct top 1 A.* from  A inner join  B on A.Process=B.Process 
    and A.Type =B.Type and A.SC!=B.SC
    where A.TC!=B.TC    
    order by sc desc
  ) as T

这是小提琴链接http://sqlfiddle.com/#!18/4bfa6/10

答案 3 :(得分:0)

您可以尝试一下。

SELECT * FROM TableA A
WHERE NOT EXISTS (
    SELECT * FROM TableB B 
    WHERE A.TC = B.TC
        AND ( A.TC <> B.TC OR A.Type <> B.Type OR A.SC <> B.SC ))

sqlfiddle

答案 4 :(得分:0)

嗯,要确切地了解自己的想法有点困难。似乎您想排除所有TC = 'C',但表B中的条目除外。

使用WHERE NOT (tc = 'C' AND A not in B) = WHERE tc <> 'C' OR A in B,我们得到:

select * 
from a
where tc <> 'C'
or exists
(
  select *
  from b
  where b.process = a.process
  and b.type = a.type
  and b.sc = a.sc
  and b.tc = a.tc
)
order by process, type, sc, tc;

诚然,这在SQL Server中有点难看。在许多其他DBMS中,我们可以仅用EXISTS来代替or (process, type, sc, tc) in (select process, type, sc, tc from b)子句。

目前尚不清楚Valid标志的作用。也许您必须在子查询中包含条件valid = 'y'