如何防止此SQL查询中的代码重复

时间:2015-08-06 13:47:52

标签: sql sql-server tsql sql-server-2014 code-duplication

这里是sql查询

第一个查询是我的主要选择查询。它将选择数百万条记录

然而,在以后的查询中,我必须使用第一个选择的UserIds。现在我唯一的解决方案就是复制这个查询

但我想知道会有更合适的解决方案吗?

SQL server 2014 Sp1

    SELECT
  UserId
FROM tblUsersProfile
WHERE (
TotalBattleCount < 20
AND Money < 200000
AND LastMoveTime < DATEADD(DAY, -30, SYSUTCDATETIME())
AND UserId IN (SELECT
  UserId
FROM tblUsersPokemons
GROUP BY UserId
HAVING COUNT(Id) < 20)
AND UserId NOT IN (SELECT
  UserId
FROM tblUsersPokemons
WHERE PokemonLevel > 90
GROUP BY UserId)
AND UserId > 3
)
OR UserId IN (SELECT
  UserId
FROM tblBannedUsers)
ORDER BY UserId ASC



DELETE FROM tblDailyRewardsParticipants
WHERE EventUserId IN (SELECT
    UserId
  FROM tblUsersProfile
  WHERE (
  TotalBattleCount < 20
  AND Money < 200000
  AND LastMoveTime < DATEADD(DAY, -30, SYSUTCDATETIME())
  AND UserId IN (SELECT
    UserId
  FROM tblUsersPokemons
  GROUP BY UserId
  HAVING COUNT(Id) < 20)
  AND UserId NOT IN (SELECT
    UserId
  FROM tblUsersPokemons
  WHERE PokemonLevel > 90
  GROUP BY UserId)
  AND UserId > 3
  )
  OR UserId IN (SELECT
    UserId
  FROM tblBannedUsers)
  ORDER BY UserId ASC)


DELETE FROM tblDailyRewardsUserParticipateCounts
WHERE UserId IN (SELECT
    UserId
  FROM tblUsersProfile
  WHERE (
  TotalBattleCount < 20
  AND Money < 200000
  AND LastMoveTime < DATEADD(DAY, -30, SYSUTCDATETIME())
  AND UserId IN (SELECT
    UserId
  FROM tblUsersPokemons
  GROUP BY UserId
  HAVING COUNT(Id) < 20)
  AND UserId NOT IN (SELECT
    UserId
  FROM tblUsersPokemons
  WHERE PokemonLevel > 90
  GROUP BY UserId)
  AND UserId > 3
  )
  OR UserId IN (SELECT
    UserId
  FROM tblBannedUsers)
  ORDER BY UserId ASC)

3 个答案:

答案 0 :(得分:2)

不确定你到底想要做什么,但你可以创建一个临时表来存储你的第一个查询数据,然后使用它来轻松完成其余的删除:

临时表插入:

SELECT UserId
INTO #TempUsersProfile
FROM tblUsersProfile tu
WHERE (
        tu.TotalBattleCount < 20
        AND tu.[MONEY] < 200000
        AND tu.LastMoveTime < DATEADD(DAY, - 30, SYSUTCDATETIME())
        AND tu.UserId IN (
            SELECT UserId
            FROM tblUsersPokemons
            GROUP BY UserId
            HAVING COUNT(Id) < 20
            )
        AND NOT EXISTS (
            SELECT UserId
            FROM tblUsersPokemons tp
            WHERE tu.UserID = tp.UserId
                AND tp.PokemonLevel > 90
            GROUP BY UserId
            )
        AND UserId > 3
        )
    OR UserId IN (
        SELECT UserId
        FROM tblBannedUsers
        )
ORDER BY UserId ASC;

删除查询:

DELETE
FROM tblDailyRewardsParticipants
WHERE EventUserId IN (SELECT UserID FROM #TempUsersProfile);

DELETE
FROM tblDailyRewardsUserParticipateCounts
WHERE UserId IN (SELECT UserID FROM #TempUsersProfile);

另外,在旁注中,我更改了您的NOT IN子句以使用NOT EXISTS

答案 1 :(得分:1)

或者你可以为你的select语句创建一个视图,并在你的删除语句中调用它......就像.....

CREATE VIEW vw_UserIds_To_Delete
AS
SELECT UserId
FROM tblUsersProfile
WHERE (
    TotalBattleCount < 20
AND Money < 200000
AND LastMoveTime < DATEADD(DAY, -30, SYSUTCDATETIME())
.................. and so on.....

然后删除语句看起来像......

DELETE FROM tblDailyRewardsParticipants
WHERE EXISTS (SELECT 1 
              FROM vw_UserIds_To_Delete 
              WHERE tblDailyRewardsParticipants.EventUserId = vw_UserIds_To_Delete.UserId)

等等

答案 2 :(得分:0)

我认为插件可以减少

SELECT UserId
INTO #TempUsersProfile
FROM tblUsersProfile tu
WHERE (
        tu.TotalBattleCount < 20
        AND tu.[MONEY] < 200000
        AND tu.LastMoveTime < DATEADD(DAY, - 30, SYSUTCDATETIME())
        AND tu.UserId IN ( 
            SELECT UserId
            FROM tblUsersPokemons
            WHERE tp.PokemonLevel <= 90
            AND UserId > 3
            GROUP BY UserId
            HAVING COUNT(Id) < 20
            )
      )
   OR UserId IN (
      SELECT UserId
      FROM tblBannedUsers
      )
ORDER BY UserId ASC;