объединение последних из различных тегов пользовательских метаданных в пользовательские строки - PullRequest
4 голосов
/ 24 августа 2008

У меня есть база данных postgres с таблицей пользователей (ИД пользователя, имя, фамилия) и таблицей метаданных пользователя (ИД пользователя, код, контент, дата и время создания). Я храню различную информацию о каждом пользователе в таблице метаданных пользователя по коду и веду полную историю. так, например, пользователь (идентификатор пользователя 15) имеет следующие метаданные:

15, 'QHS', '20', '2008-08-24 13:36:33.465567-04'  
15, 'QHE', '8', '2008-08-24 12:07:08.660519-04'  
15, 'QHS', '21', '2008-08-24 09:44:44.39354-04'  
15, 'QHE', '10', '2008-08-24 08:47:57.672058-04'  

Мне нужно получить список всех моих пользователей и самое последнее значение каждого из различных кодов метаданных пользователя. Я сделал это программно, и это было, конечно, чертовски медленно. Лучшее, что я мог понять, чтобы сделать это в SQL, - это объединить подвыборы, которые также были медленными, и мне приходилось делать по одному для каждого кода.

Ответы [ 3 ]

6 голосов
/ 26 августа 2008

На самом деле это не так сложно сделать в PostgreSQL, поскольку в его синтаксисе SELECT есть предложение "DISTINCT ON" (DISTINCT ON не является стандартным SQL).

SELECT DISTINCT ON (code) code, content, createtime
FROM metatable
WHERE userid = 15
ORDER BY code, createtime DESC;

Это ограничит возвращаемые результаты первым результатом по уникальному коду, и если вы отсортируете результаты по убыванию времени создания, вы получите самый новый из них.

1 голос
/ 24 августа 2008

Полагаю, вы не желаете изменять свою схему, поэтому я боюсь, что мой ответ может не сильно помочь, но здесь идет ...

Одним из возможных решений было бы оставить поле времени пустым до тех пор, пока оно не будет заменено более новым значением, когда вместо этого вы вставите «дату устаревания». Другой способ - расширить таблицу с помощью активного столбца, но это приведет к некоторой избыточности.

Классическим решением было бы иметь поля «Valid-From» и «Valid-To», в которых поля «Valid-To» не заполнены до тех пор, пока какая-либо другая запись не станет действительной. Это может быть легко обработано с помощью триггеров или аналогичных. Использование ограничений для проверки того, что существует только один действительный элемент каждого типа, обеспечит целостность данных.

Общим для них является то, что существует единственный способ определения набора текущих полей. Вы просто выбрали бы все записи с активным пользователем и с NULL «Valid-To» или «date of deprecation» или истинным «active».

Возможно, вас заинтересует статья в Википедии о временных базах данных и статья Консенсусный глоссарий понятий временных баз данных .

0 голосов
/ 27 августа 2008

Подвыбор - это стандартный способ сделать это. Вам просто нужно уникальное ограничение на идентификатор пользователя, код и дату - и тогда вы можете выполнить следующее:

SELECT * 
FROM Table
JOIN (
   SELECT UserId, Code, MAX(Date) as LastDate
   FROM Table
   GROUP BY UserId, Code
) as Latest ON
   Table.UserId = Latest.UserId
   AND Table.Code = Latest.Code
   AND Table.Date = Latest.Date
WHERE
   UserId = @userId
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...