6

I'd like to know how to select duplicate records except the first and last one, with the "Select by attribute/expression". On GIS SE I found a solution for selecting duplicates except the first one, with the below expression (on the picture is the current solution I have that selects all but the first duplicate):

CASE
    WHEN "PortClustersIDs3_CLUSTER_ID" IS NOT NULL
        THEN array_contains(
                array_remove_at(
                    array_agg($id, "PortClustersIDs3_CLUSTER_ID" ),
                    0),
                $id)
END

I would like to modify the above expression or write up a completely new expression for selecting all but the first as well as the last duplicate. So in the below picture/example I don't want the 20th row to be selected and the 17th row already isn't.

enter image description here


After @MrXsquared’s answer, I still have a problem with my specific case. I need to use their expression inside a CASE statement (or maybe if statement?), because I need to filter out rows when the "PortClustersIDs3_CLUSTER_ID" feature is not NULL.

As you can see from the pictures I now added it works on the first occurrence of duplicates (see 2nd screenshot) but when a few rows after the "PortClustersIDs3_CLUSTER_ID" IS NOT NULL again the code provided does not work (see 3rd screenshot). I think it's a problem with my CASE statement because you probably should be building new array for each set of rows where "PortClustersIDs3_CLUSTER_ID" is not null?

enter image description here

enter image description here

3
  • 2
    What do you want if there's exactly two duplicates? Select neither?
    – Spacedman
    Commented Nov 19, 2021 at 16:27
  • As per the help center please do not include chit chat like statements of appreciation within your posts.
    – PolyGeo
    Commented Nov 21, 2021 at 12:42
  • Set a filter "PortClustersIDs3_CLUSTER_ID" is not null, no need for case
    – Bera
    Commented Nov 21, 2021 at 17:47

1 Answer 1

5

You can use this with select by expression:

with_variable('arr',array_agg($id, "myfield"),
if($id in (@arr[0],@arr[-1]),false,true))

Or for older QGIS versions where index brackets are not supported and without the use of a variable its:

if($id in (array_first(array_agg($id, "myfield")),array_last(array_agg($id, "myfield"))),false,true)

Example result:

enter image description here

1
  • I edited the post as I am still facing a few problems, your help would be greatly appreciated! Commented Nov 21, 2021 at 12:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.