SQL当其他行是子集时删除行,没有子集时保留行

时间:2017-12-05 16:50:27

标签: sql sql-server

我有一个300,000行的数据集,看着美国收获的种植面积。一些但不是我的所有数据都被重复计算,我试图删除重复计算。数据如下所示:

Year  | State  | Crop | Practice | Acres Harvested | Acres
-------------------------------------------------------------
2008      1      1       1         1000 or more       40
2008      1      1       1         1000 to 1999       10
2008      1      1       1         2000 to 2999       30
2008      2      1       1         1000 or more       87
2008      3      2       2         1.0 to 14.9        15
2008      3      2       2         1.0 to 4.9          5
2008      3      2       2         5.0 to 14.9        10

某些行是[Acres Harvested]列中其他行的子集(第2行和第3行是第1行的子集,第6行和第7行是第5行的子集)。在我有[Acres Harvested]的更多详细信息的情况下(第2行和第3行比第1行提供更多细节),我想保留详细信息(第2行和第3行)并省略一般信息(第1行)。在其他情况下,我只有一般信息(第4行),所以这就是我要保留的内容。

我在编写代码时遇到问题,在存在详细信息时忽略一般信息,但是在更详细的信息不存在时保留一般信息。

我一直试图写一个"内部联接"我自己加入我的表,但不确定在满足某些条件时如何省略行。我有什么:

SELECT *
FROM A
INNER JOIN (SELECT *
            FROM A
            GROUP BY [YEAR], [STATE], [CROP], [PRACTICE]
            HAVING COUNT (*) > 1) AS B

ON  A.Year     =    B.Year
AND A.State    =    B.State
AND A.Crop     =    B.Crop
AND A.Practice =    B.Practice

现在我被困了......

结果应该如下:

    Year  | State  | Crop | Practice | Acres Harvested | Acres
    -------------------------------------------------------------
    2008      1      1       1         1000 to 1999       10
    2008      1      1       1         2000 to 2999       30
    2008      2      1       1         1000 or more       87
    2008      3      2       2         1.0 to 4.9          5
    2008      3      2       2         5.0 to 14.9        10

感谢任何帮助!

2 个答案:

答案 0 :(得分:0)

你的问题有点模糊。这将返回您为指定的输入数据指定的结果集:

select a.*
from a
where a.acres_harvested not like '% or more' or
      not exists (select 1
                  from a a2
                  where a2.year = a.year and a2.state = a.state and a2.crop = a.crop and
                        a2.acres_harvested like '[0-9]%to%[0-9]'
                 );

答案 1 :(得分:0)

假设您对“更详细信息”的标准是匹配集的记录,而不是像我在评论中猜到的那样以“或更多”结尾,您可以通过这种方式获得所需的输出。您只使用一条记录和分别包含多条记录的记录集,UNION而不是尝试使用一个SELECT进行记录集。

SELECT A.*
FROM A
GROUP BY [YEAR], [STATE], [CROP], [PRACTICE]
HAVING 
    COUNT (*) = 1

UNION

SELECT A.*
FROM A
INNER JOIN 
    (SELECT [YEAR], [STATE], [CROP], [PRACTICE]
        FROM A
        GROUP BY [YEAR], [STATE], [CROP], [PRACTICE]
        HAVING 
            COUNT (*) > 1
    ) AS B
ON  A.[Year]     =    B.[Year]
AND A.[State]    =    B.[State]
AND A.[Crop]     =    B.[Crop]
AND A.[Practice] =    B.[Practice]
WHERE [ACRES HARVESTED] not like '%%or more'

如果您的标准不是我想的,只需更改WHERE条款。

鉴于您更新的样本数据,您还必须检查重叠的数字范围。这个问题有一些选项可供选择:Discard existing dates that are included in the result, SQL Server。您还需要将“X到Y”值拆分为两个数字字段。