Tsql 使用生成的值和子查询选择

Tsql 使用生成的值和子查询选择,tsql,sql-server-2012,Tsql,Sql Server 2012,我有一个产品数据库,包含以下表格: 产品* 证书* 报告* 描述* 产品认证* 证书和报告 证书和说明 产品和证书、证书和报告以及证书和说明之间存在多对多关系 每个标有*的表都有一个带有时间戳的列(可以为null) 所需输出 products表的所有列+带有 0,如果行的时间戳为空 1,如果行的时间戳不为null,但任何相关实体(或其相关实体)的时间戳为null 2,如果行的时间戳不为null,并且所有相关实体(或其相关实体)的时间戳不为null 我一点也不知道如何解决这个问题 这是显

我有一个产品数据库,包含以下表格:

  • 产品*
  • 证书*
  • 报告*
  • 描述*
  • 产品认证*
  • 证书和报告
  • 证书和说明
产品和证书、证书和报告以及证书和说明之间存在多对多关系

每个标有*的表都有一个带有时间戳的列(可以为null)

所需输出

products表的所有列+带有

  • 0,如果行的时间戳为空
  • 1,如果行的时间戳不为null,但任何相关实体(或其相关实体)的时间戳为null
  • 2,如果行的时间戳不为null,并且所有相关实体(或其相关实体)的时间戳不为null
我一点也不知道如何解决这个问题


这是显示所有表如何连接在一起的查询:

   SELECT Products.*
     FROM Products
LEFT JOIN Products_Certificates
       ON Products_Certificates.ProductNumber = Products.ProductNumber
LEFT JOIN Certificates
       ON Certificates.ID = Products_Certificates.CertificateID
LEFT JOIN Certificates_Reports
       ON Certificates_Reports.CertificateID = Certificates.ID
LEFT JOIN Reports
       ON Reports.ID = Certificates_Reports.ReportID
LEFT JOIN Certificates_Descriptions
       ON Certificates_Descriptions.CertificateID = Certificates.ID
LEFT JOIN Descriptions
       ON Descriptions.ID = Certificates_Descriptions.DescriptionID

使用模拟数据并在SQL Server 2014中编写,下面是一些代码以帮助您入门-

 declare @Products table
(
  ProductNumber int not null,
  Created date
);

insert into @Products values
(1, '1/7/2019'),
(2, null),
(3, '3/4/2019'),
(4, '3/7/2019');

declare @Products_Certificates table
(
  CertificateID int not null,
  ProductNumber int not null,
  Created date
);

insert into @Products_Certificates values
(50, 1, null),
(51, 1, '2/2/2019'),
(52, 3, '2/2/2019'),
(53, 4, null),
(54, 4, null);

declare @Certificates table
(
  ID int not null,
  Created date
);

insert into @Certificates values
(50, null),
(51, '3/1/2019'),
(52, null);

with
detail as
(
  SELECT
  p.ProductNumber,
  p.Created,
  pc.CertificateID,
  c.ID,
  Products_Certs_Date_Flag = iif(pc.Created is null, 0, 1),
  Certificates_Date_Flag = iif(c.Created is null, 0, 1)
  FROM @Products p
  LEFT OUTER JOIN @Products_Certificates pc     ON pc.ProductNumber = p.ProductNumber
  LEFT OUTER JOIN @Certificates c               ON c.ID = pc.CertificateID
  /*
  LEFT OUTER JOIN @Certificates_Reports cr      ON cr.CertificateID = c.ID --no timestamp in this table
  LEFT OUTER JOIN @Reports r                    ON r.ID = cr.ReportID
  LEFT OUTER JOIN @Certificates_Descriptions cd ON cd.CertificateID = c.ID --no timestamp in this table
  LEFT OUTER JOIN @Descriptions d               ON d.ID = cd.DescriptionID;
  */
),
summary as
(
  select
  ProductNumber,
  Created,
  DateStatus = iif(Products_Certs_Date_Flag + Certificates_Date_Flag > 0, 'date exists', 'no date')
  from detail
),
pivoted as
(
  select
  ProductNumber,
  Created,
  [date exists],
  [no date]
  from summary
  pivot (count(DateStatus) for DateStatus in ([date exists], [no date])) p
)
select
ProductNumber,
Created,
Outcome =
case
  when Created is null then 0
  when [no date] > 0 then 1
  else 2
end
from pivoted
order by
ProductNumber;
以下是CTE中中间结果集的屏幕截图:
细节


摘要


旋转的


以下是最终结果:


要使其他4个表在
detail
CTE中处于活动状态,还需要做更多的工作。上面的代码为您提供了如何解决原始帖子中概述的问题的想法。此外,请仔细测试
案例
语句-如果1和2的值分配不正确,则在对实时数据运行此语句后,可能需要添加其他条件。

能否编辑原始问题并添加显示所有表如何连接在一起的查询?谢谢您的回答。我编辑了原始问题并添加了查询。您是否考虑过使用表达式?提示:使用适当的软件(MySQL、Oracle、DB2等)和版本(例如,
sql-server-2014
)标记数据库问题很有帮助。语法和特征的差异通常会影响答案。请注意,
tsql
缩小了选择范围,但没有指定数据库。您使用的是哪个版本的SQL Server?我使用的是SQL Server 2012。我研究了case表达式,但我不知道如何说“如果这个子查询的所有行中x列的值都是2”。