Я унаследовал некоторый забавный SQL и пытаюсь понять, как устранить строки с дублирующимися идентификаторами. Наши индексы хранятся в несколько столбчатых форматах, а затем мы сворачиваем все строки в один со значениями в виде разных столбцов.SQL возвращает только отдельные идентификаторы от LEFT JOIN
Нижеприведенный образец возвращает три строки уникальных данных, но идентификаторы дублируются. Мне нужно всего две строки с уникальными идентификаторами (и другими столбцами, которые идут вместе с ним). Я знаю, что я потеряю некоторые данные, но мне просто нужна одна соответствующая строка для каждого идентификатора для запроса (сначала, сверху, самой старой, самой новой, любой).
Я пробовал использовать DISTINCT, GROUP BY и ROW_NUMBER, но я продолжаю получать синтаксис неправильно или использовать их не в том месте.
Я также могу полностью переписать запрос таким образом, который можно использовать повторно, поскольку в настоящее время мне приходится генерировать это «на лету» (типы карт и cardindexes определены пользователем) и хотели бы иметь возможность создавать хранимую процедуру. Заранее спасибо!
declare @cardtypes table ([ID] int, [Name] nvarchar(50))
declare @cards table ([ID] int, [CardTypeID] int, [Name] nvarchar(50))
declare @cardindexes table ([ID] int, [CardID] int, [IndexType] int, [StringVal] nvarchar(255), [DateVal] datetime)
INSERT INTO @cardtypes VALUES (1, 'Funny Cards')
INSERT INTO @cardtypes VALUES (2, 'Sad Cards')
INSERT INTO @cards VALUES (1, 1, 'Bunnies')
INSERT INTO @cards VALUES (2, 1, 'Dogs')
INSERT INTO @cards VALUES (3, 1, 'Cat')
INSERT INTO @cards VALUES (4, 1, 'Cat2')
INSERT INTO @cardindexes VALUES (1, 1, 1, 'Bunnies', null)
INSERT INTO @cardindexes VALUES (2, 1, 1, 'playing', null)
INSERT INTO @cardindexes VALUES (3, 1, 2, null, '2014-09-21')
INSERT INTO @cardindexes VALUES (4, 2, 1, 'Dogs', null)
INSERT INTO @cardindexes VALUES (5, 2, 1, 'playing', null)
INSERT INTO @cardindexes VALUES (6, 2, 1, 'poker', null)
INSERT INTO @cardindexes VALUES (7, 2, 2, null, '2014-09-22')
SELECT TOP(100)
[ID] = c.[ID],
[Name] = c.[Name],
[Keyword] = [colKeyword].[StringVal],
[DateAdded] = [colDateAdded].[DateVal]
FROM @cards AS c
LEFT JOIN @cardindexes AS [colKeyword] ON [colKeyword].[CardID] = c.ID AND [colKeyword].[IndexType] = 1
LEFT JOIN @cardindexes AS [colDateAdded] ON [colDateAdded].[CardID] = c.ID AND [colDateAdded].[IndexType] = 2
WHERE [colKeyword].[StringVal] LIKE 'p%' AND c.[CardTypeID] = 1
ORDER BY [DateAdded]
Edit:
Хотя оба решения справедливы, я закончил с использованием раствора MAX() из @popovitsj, как это было легче реализовать. Проблема с данными, поступающими из нескольких строк, на самом деле не влияет на меня, поскольку все строки по существу являются частью одной и той же записи. Я, скорее всего, буду использовать оба решения в зависимости от моих потребностей.
Вот мой обновленный запрос (как это не совсем соответствует ответу):
SELECT TOP(100)
[ID] = c.[ID],
[Name] = MAX(c.[Name]),
[Keyword] = MAX([colKeyword].[StringVal]),
[DateAdded] = MAX([colDateAdded].[DateVal])
FROM @cards AS c
LEFT JOIN @cardindexes AS [colKeyword] ON [colKeyword].[CardID] = c.ID AND [colKeyword].[IndexType] = 1
LEFT JOIN @cardindexes AS [colDateAdded] ON [colDateAdded].[CardID] = c.ID AND [colDateAdded].[IndexType] = 2
WHERE [colKeyword].[StringVal] LIKE 'p%' AND c.[CardTypeID] = 1
GROUP BY c.ID
ORDER BY [DateAdded]
Я бы также добавил ORDER BY MAX (DateAdded), чтобы сохранить тот же порядок. На самом деле, я думаю, что вопрос повторяется до http://stackoverflow.com/questions/5391564/how-to-use-distinct-and-order-by-in-same-select-statement – sarh
Это может смешивать данные, хотя .. строка, которую вы вернетесь с вашим идентификатором, может не соответствовать ни одному из исходных строк. – Greenspark
Правда, это зависит от точных требований, если это хорошее решение. – wvdz