使用多个联接时确定组中的上次更新行

der*_*271 5 sql t-sql sql-server sql-server-2008-r2

我有以下数据:SQL Fiddle(Schema)

/* Item */
CREATE TABLE [dbo].[Item](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [Description] [nvarchar](30) NOT NULL CONSTRAINT [DF_Item_Description]  DEFAULT (''),
    [ItemLookupCode] [nvarchar](25) NOT NULL CONSTRAINT [DF_Item_ItemLookupCode]  DEFAULT (''),
    [Price] [money] NOT NULL CONSTRAINT [DF_Item_Price]  DEFAULT (0),
    [LastUpdated] [datetime] NOT NULL CONSTRAINT [DF_Item_LastUpdated]  DEFAULT (getdate()),
    [DateCreated] [datetime] NOT NULL CONSTRAINT [Df_Item_DateCreated]  DEFAULT (getdate()),
 CONSTRAINT [PK_Item] PRIMARY KEY NONCLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY]
) ON [PRIMARY]

GO

INSERT INTO [dbo].[Item] (
    [Description],
    [ItemLookupCode],
    [Price],
    [LastUpdated]
)
VALUES
  ('Product A1', 'PA1', 1, '03/01/2016 12:00:00'),
  ('Product A2', 'PA2', 2, '02/01/2016 12:00:00'),
  ('Product A3', 'PA3', 3, '01/01/2016 12:00:00'),

  ('Product B3', 'PB3', 3, '02/01/2016 12:00:00'),
  ('Product B2', 'PB2', 2, '03/01/2016 12:00:00'),
  ('Product B1', 'PB1', 1, '01/01/2016 12:00:00'),

  ('Product C2', 'PC2', 2, '02/01/2016 12:00:00'),
  ('Product C1', 'PC1', 1, '01/01/2016 12:00:00'),
  ('Product C3', 'PC3', 3, '03/01/2016 12:00:00')

GO

/* ItemClass */
CREATE TABLE [dbo].[ItemClass](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [Description] [nvarchar](30) NOT NULL CONSTRAINT [DF_ItemClass_Description]  DEFAULT (''),
    [ItemLookupCode] [nvarchar](25) NOT NULL CONSTRAINT [Df_ItemClass_ItemLookupCode]  DEFAULT (''),
    [Price] [money] NOT NULL CONSTRAINT [DF_ItemClass_Price]  DEFAULT ((0)),
 CONSTRAINT [PK_ItemClass] PRIMARY KEY NONCLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY]
) ON [PRIMARY]

GO

INSERT INTO [dbo].[ItemClass] (
    [Description],
    [ItemLookupCode],
    [Price]
)
VALUES
  ('ItemClass A', 'ICA', 1),
  ('ItemClass B', 'ICB', 2),
  ('ItemClass C', 'ICC', 3)

GO

/* ItemClassComponent */
CREATE TABLE [dbo].[ItemClassComponent](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [ItemClassID] [int] NOT NULL CONSTRAINT [DF_ItemClassComponent_ItemClassID]  DEFAULT (0),
    [ItemID] [int] NOT NULL CONSTRAINT [DF_ItemClassComponent_ItemID]  DEFAULT (0),
    [Price] [money] NOT NULL CONSTRAINT [Df_ItemClassComponent_Price]  DEFAULT (0),
 CONSTRAINT [PK_ItemClassComponent] PRIMARY KEY NONCLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY]
) ON [PRIMARY]

GO

INSERT INTO [dbo].[ItemClassComponent] (
    [ItemClassID],
    [ItemID],
    [Price]
)
VALUES
  (1, 1, 1),
  (1, 2, 1),
  (1, 3, 1),
  (2, 6, 1),
  (2, 5, 1),
  (2, 4, 1),
  (3, 8, 1),
  (3, 7, 1),
  (3, 9, 1)
GO
Run Code Online (Sandbox Code Playgroud)

我正在尝试从dbo.Item返回最新更新的每个产品的数据(在dbo.ItemClassComponent中定义).

我已经非常接近,但我的查询返回重复的行!如此接近......有人能引导我朝着正确的方向前进吗?因为TBH我不知道为什么我看到重复的行返回lol.

我的尝试:SQL小提琴

SELECT DISTINCT
    ic.Description
    ,i.ID
    ,i.Description
    ,i.ItemLookupCode
    ,i.Price
    ,i.LastUpdated
FROM Item i
INNER JOIN ItemClassComponent icc
    ON icc.ItemID = i.ID
INNER JOIN ItemClass ic
    ON ic.ID = icc.ItemClassID
INNER JOIN (
    SELECT
        MAX(_i.LastUpdated) AS LastUpdated
    FROM Item _i
    JOIN ItemClassComponent _icc
        ON _icc.ItemID = _i.ID
    GROUP BY _icc.ItemClassID
) lu
    ON lu.LastUpdated = i.LastUpdated;
Run Code Online (Sandbox Code Playgroud)

注意:我不想在那里拍打DISTINCT ......

Gor*_*off 3

我很确定您只需要比较项目类别以及上次更新日期:

SELECT . . .
FROM Item i INNER JOIN
     ItemClassComponent icc
     ON icc.ItemID = i.ID INNER JOIN
     ItemClass ic
     ON ic.ID = icc.ItemClassID INNER JOIN
     (SELECT _icc.ItemClassID, MAX(_i.LastUpdated) AS LastUpdated
      FROM Item _i JOIN
           ItemClassComponent _icc
           ON _icc.ItemID = _i.ID
      GROUP BY _icc.ItemClassID
     ) lu
    ON lu.LastUpdated = i.LastUpdated AND lu.ItemClassId = ic.Id;
Run Code Online (Sandbox Code Playgroud)

通常,我会使用窗口函数来编写:

with cte as (
      SELECT . . .,
             ROW_NUMBER() OVER (PARTITION BY icc.ItemClassId ORDER BY i.LastUpdated DESC) as seqnum
      FROM Item i INNER JOIN
           ItemClassComponent icc
           ON icc.ItemID = i.ID INNER JOIN
           ItemClass ic
           ON ic.ID = icc.ItemClassID 
    )
select *
from cte
where seqnum = 1;
Run Code Online (Sandbox Code Playgroud)