Home > Mobile >  Getting all SQL Server database records older than X days
Getting all SQL Server database records older than X days

Time:05-20

I am working on a query to delete records from the websiteTestLocation table (where websiteSnapshotStartTime is older than X days).

The (truncated) table structures look like this:

Table name Column
websiteSnapshot websiteSnapshotRecordId
websiteSnapshot websiteSnapshotStartTime
website websiteSnapshotRecordId
website websiteRecordId
websiteTestLocation websiteRecordId

The websiteTestLocation table's "websiteRecordId" is linked to the same column in the website table and website table's "websiteSnapshotRecordId" is linked to the same column in the websiteSnapshot table.

I can get all of the websiteSnapshot records (older than 1 day) using:

SELECT (websiteSnapshotId)
    FROM [dbo].websiteSnapshot
    WHERE websiteSnapshotStartTime IN (
        SELECT
            (websiteSnapshotStartTime)
        FROM
            [dbo].websiteSnapshot
        WHERE
            websiteSnapshotStartTime < DATEADD(day, -1, GETDATE())
    )

But when I include that in the rest of my query, I get the error:

Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.

The whole query looks like this:

--DELETE FROM [dbo].websiteTestLocation wtl
select * FROM [dbo].websiteTestLocation wtl
LEFT JOIN [dbo].website w ON w.websiteRecordId = wtl.websiteRecordId
LEFT JOIN [dbo].websiteSnapshot snap ON snap.websiteSnapshotId IN (w.websiteSnapshotId)
WHERE (SELECT (websiteSnapshotId)
    FROM [dbo].websiteSnapshot
    WHERE websiteSnapshotStartTime IN (
        SELECT 
            (websiteSnapshotStartTime)
        FROM
            [dbo].websiteSnapshot
        WHERE
            websiteSnapshotStartTime < DATEADD(day, -1, GETDATE())
    )) = snap.websiteSnapshotId
GO

I understand that, because a "foreach" loop would help, I must be doing something wrong. If I put "MAX" in front of "websiteSnapshotId" on line 5 and in front of websiteSnapshotStartTime on line 9, then I get data, but not all of the expected rows. I only get data from records with the "newest" websiteSnapshotStartTime that is older than 1 day.

CodePudding user response:

Break down your query bit by bit.

On the face of it this bit looks fine

select * FROM [dbo].websiteTestLocation wtl
LEFT JOIN [dbo].website w ON w.websiteRecordId = wtl.websiteRecordId

But that next JOIN is all over the place. It looks like you are trying to limit a LEFT OUTER JOIN to just the records that are in table website

LEFT JOIN [dbo].websiteSnapshot snap ON snap.websiteSnapshotId IN (w.websiteSnapshotId)

Use an INNER JOIN instead and this ON clause

ON snap.websiteSnapshotId = w.websiteSnapshotId

Next your WHERE clause - which is where the problem you report comes from. You are trying to match a single value to a list of values, that will never work. All of this

WHERE (SELECT (websiteSnapshotId)
    FROM [dbo].websiteSnapshot
    WHERE websiteSnapshotStartTime IN (
        SELECT 
            (websiteSnapshotStartTime)
        FROM
            [dbo].websiteSnapshot
        WHERE
            websiteSnapshotStartTime < DATEADD(day, -1, GETDATE())
    )) = snap.websiteSnapshotId

can be replaced with

WHERE websiteSnapshotStartTime < DATEADD(day, -1, GETDATE())
  • Related