Вернуть одну строку для каждого идентификатора на основе столбца даты (SQL) - PullRequest
0 голосов
/ 07 октября 2009

DDL создает схему и данные. Я ищу оператор , где , где он возвращает только одну строку для каждого идентификатора, и эта строка будет последней вставленной строкой на основе столбца вставленной даты.

Таким образом, результатом будет Джон, 5 и Дебби, 5

select Table1.Name, Table2.Rating
From table1 join table2 on table1.ID = table2.ID
where inserteddate = max(insertedate) 

.. для каждого удостоверения личности? Это кажется простым, но у меня блок мозга.

DDL:

CREATE TABLE [dbo].[Table1](
    [Table1ID] [int] NULL,
    [Name] [varchar](50) NULL
)

CREATE TABLE [dbo].[Table2](
    [Table2ID] [int] NULL,
    [InsertedDate] [datetime] NULL,
    [Rating] [varchar](50) NULL
)

INSERT INTO [dbo].[Table1]([Table1ID], [Name])
SELECT 1, N'John' UNION ALL
SELECT 2, N'Debbie'
INSERT INTO [dbo].[Table2]([Table2ID], [InsertedDate], [Rating])
SELECT 1, '20090101 00:00:00.000', N'6' UNION ALL
SELECT 1, '20090401 00:00:00.000', N'5' UNION ALL
SELECT 2, '20090202 00:00:00.000', N'3' UNION ALL
SELECT 2, '20090303 00:00:00.000', N'5'

Ответы [ 3 ]

0 голосов
/ 07 октября 2009
select
    table1.name,
    table2.rating
from
    table1
    inner join table2 on 
        table2.id = (select top 1 t2.id from table2 t2 where table1.id = t2.id order by t2.inserteddate desc)

о, подождите, у table2 нет первичного ключа? то ...

select
    table1.name,
    (select top 1 t2.rating 
    from table2 t2 
    where table1.id = t2.id order by t2.inserteddate desc) as last_rating
from
    table1
0 голосов
/ 07 октября 2009

Как насчет этого:

SELECT 
  Table1.Name, Table2.Rating
FROM
  table1 
INNER JOIN 
  table2 ON table1.Table1ID = table2.Table2ID
WHERE
  inserteddate = (SELECT MAX(InsertedDate) 
                    FROM Table2 t2 
                   WHERE t2.Table2ID = Table2.Table2ID)

В этом случае очень полезен индекс для столбца InsertedDate!

Или, если вы используете SQL Server 2005 и более поздние версии, вы также можете использовать CTE (общее табличное выражение) с ROW_NUMBER () и оператором PARTITION OVER, например:

WITH HelperCTE AS
(
  SELECT
    Table1.Name, Table2.Rating,
    ROW_NUMBER() OVER(PARTITION BY Table1.Table1ID 
                      ORDER BY Table2.InsertedDate DESC) AS 'RowNum'
  FROM
    table1 
  INNER JOIN
    table2 ON table1.Table1ID = table2.Table2ID
)
SELECT Name, Rating FROM HelperCTE
WHERE RowNum = 1

Это создает как «временное» представление (CTE) и нумерует записи, разделенные по Table1ID (индивидуальная нумерация для каждого отдельного Table1ID), и упорядочивает их по убыванию на InsertedDate - поэтому для каждого уникального Table1ID самая последняя запись иметь RowNum = 1.

Марк

0 голосов
/ 07 октября 2009

Я уверен, что есть лучший способ, но он сделает это:

CREATE TABLE #Table1(
    [Table1ID] [int] NULL,
    [Name] [varchar](50) NULL
)

CREATE TABLE #Table2(
    [Table2ID] [int] NULL,
    [InsertedDate] [datetime] NULL,
    [Rating] [varchar](50) NULL
)

INSERT INTO #Table1([Table1ID], [Name])
SELECT 1, N'John' UNION ALL
SELECT 2, N'Debbie'
INSERT INTO #Table2([Table2ID], [InsertedDate], [Rating])
SELECT 1, '20090101 00:00:00.000', N'6' UNION ALL
SELECT 1, '20090401 00:00:00.000', N'5' UNION ALL
SELECT 2, '20090202 00:00:00.000', N'3' UNION ALL
SELECT 2, '20090303 00:00:00.000', N'5'


select x.name, t2.rating
from 
(
select t1.table1id, t1.name, max(t2.inserteddate) as inserteddate
from #table1 t1
join
#table2 t2
on
t1.table1id = t2.table2id
group by t1.table1id, t1.name
) x
join
#table2 t2
on
x.table1id = t2.table2id
and 
x.inserteddate = t2.inserteddate
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...