【问题标题】:Is it possible to create a complicated sql query for this scenario?是否可以为这种情况创建一个复杂的 sql 查询?
【发布时间】:2020-08-19 09:22:22
【问题描述】:

是否可以创建一个返回此结果集的 SQL 查询?这里的“NA”表示不可用。您的帮助将不胜感激。谢谢。

以下是用于测试的样本数据,Sander 好心地从我的图片中转录了这些数据:

create  table CurrentProduct
(
    CategoryName nvarchar(20),
    Productname nvarchar(20)
)
GO

insert into CurrentProduct (CategoryName, Productname) values
('Cat1', 'Prod1'),
('Cat1', 'Prod2'),
('Cat2', 'Prod3'),
('Cat5', 'Prod4'),
('Cat5', 'Prod5')
GO

create  table PreviousProduct
(
    CategoryName nvarchar(20),
    Productname nvarchar(20)
)
GO

insert into PreviousProduct (CategoryName, Productname) values
('Cat1', 'Prod1'),
('Cat1', 'Prod2'),
('Cat4', 'Prod3'),
('Cat5', 'Prod4')
GO

create  table FutureProduct
(
    CategoryName nvarchar(20),
    Productname nvarchar(20)
)
GO

insert into FutureProduct (CategoryName, Productname) values
('Cat1', 'Prod1'),
('Cat1', 'Prod2'),
('Cat4', 'Prod3'),
('Cat5', 'Prod4')
GO

【问题讨论】:

  • Why is “Can someone help me?” not an actual question? 为什么标记 2 个不受支持的 SQL Server 版本,其中一个版本完全不受支持? 尝试了哪些方法,为什么没有成功?拥有 800 名声望的人应该知道为什么数据图像也不受欢迎,以及为什么包含您的尝试如此重要。花时间帮助我们帮助您。另外请注意,您在这里提出的唯一问题是“是否可以创建一个返回此结果集的 SQL 查询?”;这个问题的答案很可能是“是”。
  • 请发布文字而不是图片。另外,没有办法将 CurrentProduct 中的第二个 Cat1 行链接到 PreviousProduct 的第二个 Cat1 行(无法与 PreviousProduct 中的第一行进行区分)。
  • 这里没有负面反馈,@Humayoun_Kabir。如果您将反对票视为负面反馈,那么您就误解了它们。投反对票是为了表明投反对票的人认为该问题没有帮助或缺乏研究,并且是为了让查看该网站的其他用户知道这一点。它不是“反馈”设备。
  • 当然,我们都喜欢根据您的图像再次键入示例。
  • 虽然你很高兴为他们做这件事,@Sander,但这样做确实是 OP 的责任。不幸的是,他们现在会继续认为让其他人转录他们可以轻松复制和粘贴的内容是“可以的”......以及发布冲突标签,不表现出任何努力,或研究,或询问实际 问题。社区对问题的所有期望。

标签: sql-server sql-server-2012


【解决方案1】:

假设最后 2 个表可以在 CategoryName ProductName 上连接(否则表之间没有唯一链接)... 您可以使用 common table expressionUNION 来收集所有类别名称。

样本数据

declare @CurrentProduct table
(
    CategoryName nvarchar(5),
    ProductName nvarchar(5)
);
insert into @CurrentProduct (CategoryName, ProductName) values
('Cat1', 'Prod1'),
('Cat1', 'Prod2'),
('Cat2', 'Prod3'),
('Cat5', 'Prod4'),
('Cat5', 'Prod5');

declare @PreviousProduct table
(
    CategoryName nvarchar(5),
    ProductName nvarchar(5)
);
insert into @PreviousProduct (CategoryName, ProductName) values
('Cat1', 'Prod1'),
('Cat1', 'Prod2'),
('Cat4', 'Prod3'),
('Cat5', 'Prod4');

declare @FutureProduct table
(
    CategoryName nvarchar(5),
    ProductName nvarchar(5)
);
insert into @FutureProduct (CategoryName, ProductName) values
('Cat1', 'Prod1'),
('Cat1', 'Prod2'),
('Cat4', 'Prod3'),
('Cat5', 'Prod4');

解决方案

with cte_cat as
(
    select cp.CategoryName from @CurrentProduct cp
        union
    select pp.CategoryName from @PreviousProduct pp
        union
    select fp.CategoryName from @FutureProduct fp
)
select  c.CategoryName,
        coalesce(cp.ProductName, 'NA') as 'CurrentProd',
        coalesce(pp.ProductName, 'NA') as 'PrevProd',
        coalesce(fp.ProductName, 'NA') as 'FtrProd'
from cte_cat c
left join @CurrentProduct cp
    on  cp.CategoryName = c.CategoryName
outer apply (   select top 1 pp.ProductName
                from @PreviousProduct pp
                where pp.CategoryName = c.CategoryName
                  and pp.ProductName = coalesce(cp.ProductName, pp.ProductName) ) pp
outer apply (   select top 1 fp.ProductName
                from @FutureProduct fp
                where fp.CategoryName = c.CategoryName
                  and fp.Productname = coalesce(cp.Productname, fp.ProductName) ) fp;

结果

CategoryName CurrentProd PrevProd FtrProd
------------ ----------- -------- -------
Cat1         Prod1       Prod1    Prod1
Cat1         Prod2       Prod2    Prod2
Cat2         Prod3       NA       NA
Cat4         NA          Prod3    Prod3
Cat5         Prod4       Prod4    Prod4
Cat5         Prod5       NA       NA

【讨论】:

  • 这当然有效,尽管在这里对每个表进行 2 次扫描(使用 UNION)似乎有点贵。使用UNION ALL 然后取消透视数据可能会更好。
  • 谢谢@Sander。
猜你喜欢
  • 2015-06-23
  • 1970-01-01
  • 2013-08-25
  • 2015-12-14
  • 1970-01-01
  • 1970-01-01
  • 2014-05-07
  • 2013-02-25
  • 1970-01-01
相关资源
最近更新 更多