【问题标题】:TSQL get COUNT of rows that are missing from right tableTSQL 获取右表中缺少的行数
【发布时间】:2016-08-18 13:46:01
【问题描述】:

还有另一个类似的答案,但它有 2 页长,我的要求不需要。我有 2 个表,tableA 和一个 tableB,我需要找到 tableA 中存在但 tableB 中不存在的行的计数,或者如果 tableB 中的 update_on 不是今天的日期。

我的桌子:

tableA:

release_id      book_name        release_begin_date  
----------------------------------------------------
1122           midsummer          2016-01-01          
1123           fool's errand      2016-06-01          
1124           midsummer          2016-04-01          
1125         fool's errand        2016-08-01            

tableB:

release_id   book_name        updated_on
-----------------------------------------
1122         midsummer          2016-08-17 
1123         fool's errand      2016-08-16**  

预期结果:由于每本书都缺少一个版本 ID,因此计数为 1。但是另外表B中的傻瓜差事已有的行updated_on日期是昨天而不是今天,需要计入count_of_not_updated。

book_name       count_of_missing  count_of_not_updated
-------------------------------------------------------
midsummer          1                 0
fool's errand      1                 1

注意:即使傻瓜的差事出现在表 B 中,我也需要在 count_of_missing 中显示它,因为它的 updated_on 日期是昨天而不是今天。我知道它必须是左连接和其他东西的组合,但这里的踢球者不仅从左表中获取丢失的行,而且同时检查 updated_on 表是否是今天的日期,如果不是,则计算该行在 count_of_not_updated 中。

【问题讨论】:

  • 我发现您的最后一个注释有点令人困惑 - 从您的预期结果看来,您有 1 个因傻瓜差事而丢失(ID 1125)和 1 个未更新(1123)。但是您是说您还需要 1123 才能算作失踪?那么在 count_of_missing 列中,傻瓜的差事不会是 2 吗?
  • @TPhe - 傻瓜的差事丢失了一行,因此 count_of_missing 中为 1,但表 B 中用于傻瓜差事的现有行的更新日期不是今天(当前日期/getdate()),因此count_of_not_updated 中的 1 个。与 midsummer 不同,它缺少一行,并且存在的行的 updated_on 日期为今天(当天)
  • 好的,在这种情况下,我将编辑我的查询。您的问题“注意:即使傻瓜的差事出现在表 B 中,我也需要在 count_of_missing 中显示它,因为它的更新日期是昨天而不是今天”中的句子仍然让我感到困惑。
  • 请阅读this,了解一些改进问题的技巧。使用适当的软件(MySQL、Oracle、DB2 等)和版本标记数据库问题很有帮助,例如sql-server-2014。语法和功能的差异通常会影响答案。

标签: sql-server tsql


【解决方案1】:
select sum(case when b.release_id is null then 1 else 0 end) as noReleaseID 
     , sum(case when datediff(d, b.release_date, getdate()) > 0 then 1 else 0 end) as releaseDateNotToday
     , a.release_id
from tableA a 
left outer join tableB b on a.release_id = b.release_id
Group by a.release_id

此示例使用case statement 上的sum function 将case 语句返回true 的实例相加。请注意,与您的示例一样,当前代码假定您正在计算表 b 中的所有旧发行日期 - 如果每本书在表 b 中有多个旧发行日期,并且您只想比较最近的发布日期。

【讨论】:

  • 我没有关注你的左连接 - 它有列名而不是表名,如下所示:tableA 左外连接 tableB 在 tableA.release_id = tableB.release_id 和 tableA.book_name = tableB.book_name。
  • @DamonMatt 我的错误,这是一个复制/粘贴错误。它应该只是 tableA 与 tableB 的左连接。我已经编辑了我的帖子。
  • 如您所说,实际查询中涉及更多列,但这为我提供了工作框架。感谢您的帮助 - 接受了您的回答。
  • 我忘了问你 - 我如何获得 tableA 中 release_id 的总数?这将是表 A 中的 release_id 总数 - 现在如果我执行计数(a.release_id),该计数与 noreleaseid 的计数匹配,这是不正确的 - 计数(a.release_id)应该大于 noreleaseid 计数.
  • 另外,你的 datediff 正在检查 > 0,那不应该是 = 0 吗?
【解决方案2】:

试试这个

DECLARE @tableA TABLE (release_id  INT, book_name  NVARCHAR(50), release_begin_date  DATETIME)
DECLARE @tableB TABLE (release_id  INT, book_name  NVARCHAR(50), updated_on  DATETIME)

INSERT INTO @tableA
VALUES
(1122,  'midsummer',          '2016-01-01'),          
(1123,  'fool''s errand',      '2016-06-01'),          
(1124,  'midsummer',          '2016-04-01'),          
(1125,  'fool''s errand',      '2016-08-01') 


INSERT INTO @tableB
VALUES
(1122, 'midsummer',      '2016-08-17'), 
(1123, 'fool''s errand',  '2016-08-16')

;WITH TmpTableA
AS
(
    SELECT
        book_name,
        COUNT(1) CountOfTableA
    FROM
        @tableA
    GROUP BY
        book_name
), TmpTableB
AS 
(
    SELECT
        book_name,
        COUNT(1) CountOfTableB,
        SUM(CASE WHEN CONVERT(VARCHAR(11), updated_on, 112) = CONVERT(VARCHAR(11), GETDATE(), 112) THEN 0 ELSE 1 END) count_of_not_updated
    FROM
        @tableB
    GROUP BY
        book_name
)


SELECT
    A.book_name ,
    A.CountOfTableA - ISNULL(B.CountOfTableB, 0) AS count_of_missing,
    ISNULL(B.count_of_not_updated, 0) AS count_of_not_updated
FROM
    TmpTableA A LEFT JOIN 
    TmpTableB B ON A.book_name = B.book_name

结果:

book_name            count_of_missing count_of_not_updated
-------------------- ---------------- --------------------
fool's errand        1                1
midsummer            1                1

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-05-28
    • 1970-01-01
    • 1970-01-01
    • 2023-04-08
    • 1970-01-01
    • 2012-09-01
    • 1970-01-01
    相关资源
    最近更新 更多