2013-05-14 4 views
1

У меня есть таблица со следующими столбцамиSQL для фильтрации записей на основе другого запроса на одной и той же таблицы

  1. TrialId
  2. Очки
  3. TrialDateTime
  4. UserId

Это представляет испытания сделанный пользователем & баллов, которые он забил в ходе судебного разбирательства. Определенный пользователь может выполнить 10 испытаний, чтобы он мог иметь 10 записей в таблице.

Я хочу получить все записи, в которых точки были скреплены, чем 50, но только в том случае, если это испытание представляет собой четвертую или более пробную версию этого конкретного пользователя. Номер конкретного испытания не представлен в таблице. Однако, если у пользователя есть 5 проб, тогда поле datetime можно использовать для определения, которое является первым/вторым и т.д.

Итак, в основном я хочу получить все испытания, где оценка больше 50 & тот же идентификатор пользователя имеет 3 других других испытания в таблице, которые имеют меньшую дату и время.

Есть ли способ сделать это через SQL?

Я знаю, что я могу получить

select * from tbl where points > 50; 

получите мне все записи, где точки> 50, но как я могу фильтровать его дальше?

Если бы я имел DateTime конкретной записи в переменную с именем X, я мог бы сделать

select count(TrialId) from tbl where TrialDateTime > 'somedatetime' and userid = 'someuid'. 

, чтобы проверить, есть ли более чем 3 старые записи для того же идентификатора пользователя. Но есть ли способ объединить оба этих метода с использованием SQL? Какие у меня есть другие варианты?

Примеры записи

1. T1, 20, 2013-05-09 14:10:27.000, U1 
2. T2, 40, 2013-05-09 14:20:27.000, U1 
3. T3, 45, 2013-05-09 14:30:27.000, U1 
4. T4, 60, 2013-05-09 14:40:27.000, U1 
5. T5, 20, 2013-05-09 12:11:27.000, U2 
6. T6, 30, 2013-05-09 12:12:27.000, U2 
7. T7, 60, 2013-05-09 12:13:27.000, U2 
8. T8, 40, 2013-05-09 12:54:27.000, U2 

Здесь Запись 4 будут выбраны. Однако запись 7 не будет выбрана, хотя оба имеют оценки выше 50.

Использование SQL Server 2008 R2.

+0

можете ли вы предоставить образцы записей? –

+0

Какую версию sql-сервера вы используете? – Arion

+0

@JW 웃 - добавлены образцы записей. – user93353

ответ

3

Может быть что-то вроде этого:

;WITH CTE 
AS 
(
    SELECT 
     ROW_NUMBER() OVER(PARTITION BY t.UserId 
          ORDER BY t.TrialDateTime) AS NbrOfTrails, 
     t.* 
    FROM 
     tbl AS t 
) 
SELECT 
    * 
FROM 
    CTE 
WHERE 
    CTE.NbrOfTrails > 3 
    AND CTE.Points > 50 

Ссылки:

Using Common Table Expressions

ROW_NUMBER (Transact-SQL)

+0

Очень интересно !!!! Позвольте мне проверить это. – user93353

+0

Имеет ли это зависимость от SQL Server 2008? то есть будет ли он работать с SQL Server 2005? – user93353

+0

@ user93353: Я обновил ответ с некоторыми ссылками. Если вы прочтете ссылку, вы увидите, что она не имеет зависимости от 2008 года. Она также будет работать в 2005 году – Arion

0

Я верю, что вы можете сделать следующее:

SELECT 
     * 
    FROM 
     tbl as outertable 
    WHERE 
     points > 50 AND 
     (
      SELECT 
        COUNT(*) AS Number 
       FROM 
        tbl as innertable 
       WHERE 
        innertable.UserID = outertable.UserID AND 
        innertable.TrialDateTime < outertable.TrialDateTime 
     ) > 2 
Смежные вопросы