简体   繁体   English

使用 SQL 从单个表中进行选择

[英]Selecting within a selection using SQL from a single table

I have to make a query inside another query in order to find entries in a table that have characteristics but not others.我必须在另一个查询中进行查询,以便在表中找到具有特征但没有其他特征的条目。 The characteristics are derived from a connection to another table.这些特征来自与另一个表的连接。

Basically, I have a plans table and a parcels table.基本上,我有一个计划表和一个包裹表。 I need to find the plans that relate to both (building strata, bareland strata, common ownership) and (road, subdivision, park, interest).我需要找到与(建筑地层、裸地地层、共同所有权)和(道路、细分、公园、利益)相关的计划。 These plans should contain entries in one list, but not both.这些计划应在一个列表中包含条目,但不能同时包含两者。

Here is what I have so far.这是我到目前为止所拥有的。

SELECT * 
FROM parcelfabric_plans 
WHERE 
(name in 
    (select pl.name from parcelfabric_parcels p inner join 
     parcelfabric_plans pl on p.planid = pl.objectid
        WHERE
            p.parcelclass IN ( 'ROAD', 'SUBDIVISION', 'PARK', 'INTEREST')))

This is the first query, which gets all the plans that have parcels related to them in this list.这是第一个查询,它在此列表中获取所有与他们相关的包裹的计划。 How do I query this selection to get plans within this selection that are also related to the second list (subdivisions, interests, roads, parks)?如何查询此选择以获取此选择中也与第二个列表(细分、兴趣、道路、公园)相关的计划?

This query returns 268983 results of plans.此查询返回 268983 个计划结果。 Of these results, I would like to be able to query them and get the number of plans that are also related to subdivisions, interests, roads, parks.在这些结果中,我希望能够查询它们并获得与细分、兴趣、道路、公园相关的计划数量。

This would require elements from both lists:这将需要两个列表中的元素:

select pl.name
from parcelfabric_plans pl
where exists (
    select 1 from parcelfabric_parcels p 
    where p.planid = pl.objectid
        and p.parcelclass in ('ROAD', 'SUBDIVISION', 'PARK', 'INTEREST')
) and exists (
    select 1 from parcelfabric_parcels p 
    where p.planid = pl.objectid
        and p.parcelclass in (<list 2>)
) 

I'm not clear about the requirement though.虽然我不清楚要求。 If you want them to be mutually exclusive then I think this is a better idea:如果您希望它们相互排斥,那么我认为这是一个更好的主意:

with data as (
    select p.planid,
        count(case when p.parcelclass in
            ('ROAD', 'SUBDIVISION', 'PARK', 'INTEREST') then 1 end) as cnt1,
        count(case when p.parcelclass in
            (<list 2>) then 1 end) as cnt2
    from parcelfabric_plans pl inner join parcelfabric_parcels p
        on p.planid = pl.objectid
    -- possible optimization
    /* where p.parcelclass in (<combined list>) */
    group by p.planid
)
select * from data
where cnt1 > 0 and cnt2 = 0 or cnt1 = 0 and cnt2 > 0;

I would like to thank everyone for their comments and answers.我要感谢大家的评论和回答。 I figured out a solution, though it is quite clunky.我想出了一个解决方案,虽然它很笨重。 But at least it works.但至少它有效。

    SELECT * 
FROM pmbcprod.pmbcowner.ParcelFabric_Plans 

WHERE 
(name in
    (select pl.name from parcelfabric_parcels p inner join parcelfabric_plans pl on p.planid = pl.objectid
        WHERE
            p.parcelclass IN ('ROAD','INTEREST','SUBDIVISION','PARK') 
)and name in
    (select pl.name from parcelfabric_parcels p inner join parcelfabric_plans pl on p.planid = pl.objectid
        WHERE
            p.parcelclass IN ('BUILDING STRATA','COMMON OWNERSHIP','BARE LAND STRATA')
)
)

What I was after was simpler than I thought, I just needed to wrap my head around the structure.我所追求的比我想象的要简单,我只需要把头绕在结构上。 It's basically a nested query (subquery?).它基本上是一个嵌套查询(子查询?)。 The inner query is made, then the next one is formed around it.进行内部查询,然后围绕它形成下一个查询。

Again, thank you and it is much appreciated.再次感谢您,非常感谢。 Cheers to all.祝大家欢呼。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM