计算distinct和join之间的差异

时间:2014-11-29 17:21:46

标签: sql sql-server join sql-server-2008-r2 distinct

如何计算不同行的数量减去这些相同的不同行的连接数?

如果用户没有提交行的权限,我正在编写触发器之后需要引发错误的触发器。我可以在两个陈述中做到这一点,但这似乎效率低下。

DECLARE @AccessibleCount INT =
(
    SELECT
        COUNT(DISTINCT i.[ParentId])
    FROM
        inserted i
    INNER JOIN [SuperSecret].[Parent] AS p ON
        p.[Id] = i.[ParentId] AND
        p.[LockedBy] = @UserId
);

DECLARE @ActualCount INT = (SELECT COUNT(DISTINCT [ParentId]) FROM inserted);
IF (@AccessibleCount <> @ActualCount)
BEGIN
    RAISERROR(...);
    ROLLBACK TRANSACTION;
END

出于性能的考虑,似乎我应该在两个计数的不同inserted.ParentId上使用子查询。我尝试了以下操作,但导致“无效的对象名称'我'。”

DECLARE @ActualMinusAccessible INT =
(
    SELECT
        COUNT(*)
            -
        (
            SELECT
                COUNT(*)
            FROM
                i
            INNER JOIN [SuperSecret].[Parent] AS p ON
                p.[Id] = i.[ParentId] AND
                p.[LockedBy] = @UserId
        )
    FROM
        (
            SELECT DISTINCT [ParentId] FROM inserted
        ) AS i
);

IF (@ActualMinusAccessible <> 0)
BEGIN
    RAISERROR (...);
    ROLLBACK TRANSACTION;
END

1 个答案:

答案 0 :(得分:0)

如果没有错,您希望Raise Error [ParentId] 插入[SuperSecret].[Parent]表中不存在。尝试像这样更改SQL查询。

IF EXISTS (SELECT 1
           FROM   inserted i
           WHERE  NOT EXISTS (SELECT 1
                              FROM   [SuperSecret].[Parent] a
                              WHERE  i.[ParentId] = a.[ParentId] AND a.[LockedBy] = @UserId))
  BEGIN
      RAISERROR (...);
      ROLLBACK TRANSACTION;
  END 

OR

IF (SELECT Count(DISTINCT [ParentId]) - (SELECT Count(DISTINCT i.[ParentId])
                                         FROM   inserted i
                                                INNER JOIN [SuperSecret].[Parent] AS p
                                                        ON p.[Id] = i.[ParentId]
                                                           AND p.[LockedBy] = @UserId)
    FROM   inserted) <> 0
  BEGIN
      RAISERROR (...);
      ROLLBACK TRANSACTION;
  END