我有一个表,其中一列有重复记录,但其他列是不同的。所以像这样
代码子代码版本状态
1234 D1 1 A
1234 D1 0 P
1234 DA 1 A
1234 DB 1 P
5678 BB 1 A
5678 BB 0 P
5678 BP 1 A
5678 BJ 1 A
0987 HH 1 A
所以在上表中。子代码和版本是唯一值,而代码重复。我想将上表中的记录转移到临时表中。只有我想要传输的记录才是代码的所有子代码都具有“A”的状态,我只想在临时表中使用它们一次。
所以从上面的例子开始。临时表应该只有 5678和0987,因为所有相对于5678的子节点都具有'A'状态,并且0987的所有子节点(它只有一个)具有A的状态。由于其子代码'DB'的状态为'P'
我很感激任何帮助!
答案 0 :(得分:1)
关于版本栏是否发挥作用,有点不清楚。例如,您是否只想考虑具有最大版本的行,或者如果任何子类具有“A”,则它是否计数。以5678,例如BB为例,其中版本1具有“A”而版本0具有“B”。是否包含5678因为至少有一个子代码BB具有“A”或者是因为版本1具有“A”。
以下代码假定您希望所有代码中每个子代码至少有一个“A”,无论版本如何。
SELECT
T1.code,
T1.subcode,
T1.version,
T1.status
FROM
MyTable T1
WHERE
(
SELECT COUNT(DISTINCT subcode)
FROM MyTable T2
WHERE T2.code = T1.code
) =
(
SELECT COUNT(DISTINCT subcode)
FROM MyTable T3
WHERE T3.code = T1.code AND T3.status = 'A'
)
如果你的桌子很大,表现可能会很糟糕。我会尝试提出一个可能会有更好性能的查询,因为这是我的头脑。
另外,如果你解释问题的全部范围,也许我们可以找到摆脱那个临时表的方法......;)
以下是两种可能的方法。仍然有很多子查询,但它们看起来会比上面的方法表现更好。它们都非常相似,虽然第二个在我的数据库中有更好的查询计划。当然,数据有限,没有索引,这不是一个很好的测试。您应该尝试所有方法,看看哪种方法最适合您的数据库。
SELECT
T1.code,
T1.subcode,
T1.version,
T1.status
FROM
MyTable T1
WHERE
EXISTS
(
SELECT *
FROM MyTable T2
WHERE T2.code = T1.code
AND T2.status = 'A'
) AND
NOT EXISTS
(
SELECT *
FROM MyTable T3
LEFT OUTER JOIN MyTable T4 ON
T4.code = T3.code AND
T4.subcode = T3.subcode AND
T4.status = 'A'
WHERE T3.code = T1.code
AND T3.status <> 'A'
AND T4.code IS NULL
)
SELECT
T1.code,
T1.subcode,
T1.version,
T1.status
FROM
MyTable T1
WHERE
EXISTS
(
SELECT *
FROM MyTable T2
WHERE T2.code = T1.code
AND T2.status = 'A'
) AND
NOT EXISTS
(
SELECT *
FROM MyTable T3
WHERE T3.code = T1.code
AND T3.status <> 'A'
AND NOT EXISTS
(
SELECT *
FROM MyTable T4
WHERE T4.code = T3.code
AND T4.subcode = T3.subcode
AND T4.status = 'A'
)
)
答案 1 :(得分:1)
这是我的解决方案
SELECT Code
FROM
(
SELECT
Code,
COUNT(SubCode) as SubCodeCount
SUM(CASE WHEN ACount > 0 THEN 1 ELSE 0 END)
as SubCodeCountWithA
FROM
(
SELECT
Code,
SubCode,
SUM(CASE WHEN Status = 'A' THEN 1 ELSE 0 END)
as ACount
FROM CodeTable
GROUP BY Code, SubCode
) sub
GROUP BY Code
) sub2
WHERE SubCodeCountWithA = SubCodeCount
让我们从内到外打破它。
SELECT
Code,
SubCode,
SUM(CASE WHEN Status = 'A' THEN 1 ELSE 0 END)
as ACount
FROM CodeTable
GROUP BY Code, SubCode
对代码和子代码进行分组(每行是代码和子代码的不同配对)。查看每个配对中发生的A数。
SELECT
Code,
COUNT(SubCode) as SubCodeCount
SUM(CASE WHEN ACount > 0 THEN 1 ELSE 0 END)
as SubCodeCountWithA
FROM
--previous
GROUP BY Code
按代码重新组合这些配对(现在每行都是一个代码)并计算有多少个子代码,以及有多少个子代码有一个A.
SELECT Code
FROM
--previous
WHERE SubCodeCountWithA = SubCodeCount
使用与A的子代码具有相同数量的子码来发出这些代码。
答案 2 :(得分:0)
在您的选择中,添加一个where子句,内容为:
Select [stuff]
From Table T
Where Exists
(Select * From Table
Where Code = T.Code
And Status = 'A')
And Not Exists
(Select * From Table I
Where Code = T.Code
And Not Exists
(Select * From Table
Where Code = I.Code
And SubCode = I.SubCode
And Status = 'A'))
英文 告诉我行, 至少有一行状态为“A”的行, 并且没有任何特定子代码的行, 没有至少一行代码/子代码,状态为“A”
答案 3 :(得分:-1)
INSERT theTempTable (Code)
SELECT t.Code
FROM theTable t
LEFT OUTER JOIN theTable subT ON (t.Code = subT.Code AND subT.status <> 'A')
WHERE subT.Code IS NULL
GROUP BY t.Code
这应该可以解决问题。逻辑有点棘手,但我会尽力解释它是如何派生出来的。
外部联接与IS NULL检查相结合,允许您搜索条件的缺席。将其与您正常查找的内容相反(在本例中为status ='A'),当没有与不匹配的行时查询成功。这与((没有行)OR(所有行匹配)相同。由于我们知道由于表上的其他查询而存在行,因此所有行都必须匹配。