Извлечь строку, которая имеет значение Max для столбца

С Python 3 функция print - это функция, а не оператор, поэтому вам нужны скобки вокруг аргументов, как в print("continue"), если вы использовали Python 3.

однако, указывает на более раннюю позицию, чем на Python 3, поэтому вместо этого вы должны использовать Python 2.x. В этом случае ошибка возникает из-за того, что вы вводите это в интерактивном интерпретаторе, и ему нужна небольшая «помощь», чтобы выяснить, что вы пытаетесь сказать. Введите пустую строку после предыдущего блока, чтобы он мог правильно расшифровать отступ, как в этом:

>>> try:
...     fsock = open("/bla")
... except IOError:
...     print "Caught"
...
(some output shows here)
>>> print "continue"
545
задан Gurwinder Singh 26 March 2017 в 12:18
поделиться

21 ответ

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

select userid,
       my_date,
       ...
from
(
select userid,
       my_date,
       ...
       max(my_date) over (partition by userid) max_my_date
from   users
)
where my_date = max_my_date

"Аналитические функции качаются"

Редактирование: Относительно первого комментария...

"использующие аналитические запросы и самосоединение побеждает цель аналитических запросов"

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

"Окно по умолчанию в Oracle от первой строки в разделе к текущему"

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

работы кода.

381
ответ дан 4 revs, 3 users 96% 26 March 2017 в 12:18
поделиться
select userid, value, date
  from thetable t1 ,
       ( select t2.userid, max(t2.date) date2 
           from thetable t2 
          group by t2.userid ) t3
 where t3.userid t1.userid and
       t3.date2 = t1.date

, по моему скромному мнению, это работает. HTH

1
ответ дан Zsolt Botykai 26 March 2017 в 12:18
поделиться

Я думаю, что это должно работать?

Select
T1.UserId,
(Select Top 1 T2.Value From Table T2 Where T2.UserId = T1.UserId Order By Date Desc) As 'Value'
From
Table T1
Group By
T1.UserId
Order By
T1.UserId
1
ответ дан GateKiller 26 March 2017 в 12:18
поделиться

Сначала попробуйте, я неправильно читал вопрос, после главного ответа, вот полный пример с корректными результатами:

CREATE TABLE table_name (id int, the_value varchar(2), the_date datetime);

INSERT INTO table_name (id,the_value,the_date) VALUES(1 ,'a','1/1/2000');
INSERT INTO table_name (id,the_value,the_date) VALUES(1 ,'b','2/2/2002');
INSERT INTO table_name (id,the_value,the_date) VALUES(2 ,'c','1/1/2000');
INSERT INTO table_name (id,the_value,the_date) VALUES(2 ,'d','3/3/2003');
INSERT INTO table_name (id,the_value,the_date) VALUES(2 ,'e','3/3/2003');

-

  select id, the_value
      from table_name u1
      where the_date = (select max(the_date)
                     from table_name u2
                     where u1.id = u2.id)

-

id          the_value
----------- ---------
2           d
2           e
1           b

(3 row(s) affected)
1
ответ дан KyleLanser 26 March 2017 в 12:18
поделиться

Это должно быть столь же просто как:

SELECT UserId, Value
FROM Users u
WHERE Date = (SELECT MAX(Date) FROM Users WHERE UserID = u.UserID)
1
ответ дан DarthJDG 26 March 2017 в 12:18
поделиться

Принятие Даты уникально для данного UserID, вот некоторый TSQL:

SELECT 
    UserTest.UserID, UserTest.Value
FROM UserTest
INNER JOIN
(
    SELECT UserID, MAX(Date) MaxDate
    FROM UserTest
    GROUP BY UserID
) Dates
ON UserTest.UserID = Dates.UserID
AND UserTest.Date = Dates.MaxDate 
2
ответ дан DarthJDG 26 March 2017 в 12:18
поделиться

Если (UserID, Дата) уникально, т.е. никакая дата не появляется дважды для того же пользователя тогда:

select TheTable.UserID, TheTable.Value
from TheTable inner join (select UserID, max([Date]) MaxDate
                          from TheTable
                          group by UserID) UserMaxDate
     on TheTable.UserID = UserMaxDate.UserID
        TheTable.[Date] = UserMaxDate.MaxDate;
0
ответ дан finnw 26 March 2017 в 12:18
поделиться

Я думаю что-то вроде этого. (Простите мне за любые ошибки синтаксиса; я привык использовать HQL в этой точке!)

РЕДАКТИРОВАНИЕ: Также неправильно читайте вопрос! Исправленный запрос...

SELECT UserId, Value
FROM Users AS user
WHERE Date = (
    SELECT MAX(Date)
    FROM Users AS maxtest
    WHERE maxtest.UserId = user.UserId
)
2
ответ дан jdmichal 26 March 2017 в 12:18
поделиться
Select  
   UserID,  
   Value,  
   Date  
From  
   Table,  
   (  
      Select  
          UserID,  
          Max(Date) as MDate  
      From  
          Table  
      Group by  
          UserID  
    ) as subQuery  
Where  
   Table.UserID = subQuery.UserID and  
   Table.Date = subQuery.mDate  
3
ответ дан Aheho 26 March 2017 в 12:18
поделиться

(T-SQL) Сначала получает всех пользователей и их maxdate. Соединение с таблицей для нахождения соответствующих значений для пользователей на maxdates.

create table users (userid int , value int , date datetime)
insert into users values (1, 1, '20010101')
insert into users values (1, 2, '20020101')
insert into users values (2, 1, '20010101')
insert into users values (2, 3, '20030101')

select T1.userid, T1.value, T1.date 
    from users T1,
    (select max(date) as maxdate, userid from users group by userid) T2    
    where T1.userid= T2.userid and T1.date = T2.maxdate

результаты:

userid      value       date                                    
----------- ----------- -------------------------- 
2           3           2003-01-01 00:00:00.000
1           2           2002-01-01 00:00:00.000
2
ответ дан boes 26 March 2017 в 12:18
поделиться

я вещь Вы shuold делаю этот вариант к предыдущему запросу:

SELECT UserId, Value FROM Users U1 WHERE 
Date = ( SELECT MAX(Date)    FROM Users where UserId = U1.UserId)
2
ответ дан stefano m 26 March 2017 в 12:18
поделиться

У меня нет Oracle для тестирования его, но наиболее эффективное решение должно использовать аналитические запросы. Это должно выглядеть примерно так:

SELECT DISTINCT
    UserId
  , MaxValue
FROM (
    SELECT UserId
      , FIRST (Value) Over (
          PARTITION BY UserId
          ORDER BY Date DESC
        ) MaxValue
    FROM SomeTable
  )

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

, Если бы Вы хотите узнать об аналитических запросах, я предложил бы читать http://www.orafaq.com/node/55 и <забастовка> http://www.akadia.com/services/ora_analytic_functions.html . Вот краткое изложение.

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

В этом случае вот то, что делает внутренний запрос. Целый набор данных отсортирован по UserId тогда Дата DESC. Тогда это обрабатывает его в одной передаче. Для каждой строки Вы возвращаете UserId и первое свидание, видевшее, что UserId (так как даты отсортированы DESC, это - макс. дата). Это дает Вам Ваш ответ с дублированными строками. Тогда внешнее ОТЛИЧНОЕ давит дубликаты.

Это не особенно захватывающий пример аналитических запросов. Поскольку намного большая победа рассматривает взятие таблицы финансовых получений и вычисления для каждого пользователя и получения, рабочего общего количества того, что они заплатили. Аналитические запросы решают это эффективно. Другие решения менее эффективны. Который является, почему они - часть стандарта SQL 2003 года. (К сожалению, Пост-ГРЭС еще не имеет их. Grrr...)

7
ответ дан Andrew Barber 26 March 2017 в 12:18
поделиться

Я знаю, что Вы попросили Oracle, но в SQL 2005 мы теперь используем это:


-- Single Value
;WITH ByDate
AS (
SELECT UserId, Value, ROW_NUMBER() OVER (PARTITION BY UserId ORDER BY Date DESC) RowNum
FROM UserDates
)
SELECT UserId, Value
FROM ByDate
WHERE RowNum = 1

-- Multiple values where dates match
;WITH ByDate
AS (
SELECT UserId, Value, RANK() OVER (PARTITION BY UserId ORDER BY Date DESC) Rnk
FROM UserDates
)
SELECT UserId, Value
FROM ByDate
WHERE Rnk = 1
13
ответ дан mancaus 26 March 2017 в 12:18
поделиться

Я не знаю Ваши точные названия столбцов, но это было бы что-то вроде этого:

    select userid, value
      from users u1
     where date = (select max(date)
                     from users u2
                    where u1.userid = u2.userid)
49
ответ дан Steve K 26 March 2017 в 12:18
поделиться

Не работать, у меня нет Oracle для вручения, но я, кажется, вспоминаю, что Oracle позволяет нескольким столбцам быть согласованными в В пункте, который должен, по крайней мере, избежать опций, которые используют связанный подзапрос, который редко является хорошей идеей.

Что-то вроде этого, возможно (не может помнить, должен ли список столбцов быть заключен в скобки или не):

SELECT * 
FROM MyTable
WHERE (User, Date) IN
  ( SELECT User, MAX(Date) FROM MyTable GROUP BY User)

РЕДАКТИРОВАНИЕ: Просто попробованный это за реальный:

SQL> create table MyTable (usr char(1), dt date);
SQL> insert into mytable values ('A','01-JAN-2009');
SQL> insert into mytable values ('B','01-JAN-2009');
SQL> insert into mytable values ('A', '31-DEC-2008');
SQL> insert into mytable values ('B', '31-DEC-2008');
SQL> select usr, dt from mytable
  2  where (usr, dt) in 
  3  ( select usr, max(dt) from mytable group by usr)
  4  /

U DT
- ---------
A 01-JAN-09
B 01-JAN-09

, Таким образом, это работает, хотя часть нового-fangly материала, упомянутого в другом месте, может быть более производительной.

35
ответ дан Mike Woodhouse 26 March 2017 в 12:18
поделиться
SELECT userid, MAX(value) KEEP (DENSE_RANK FIRST ORDER BY date DESC)
  FROM table
  GROUP BY userid
156
ответ дан Dave Costa 26 March 2017 в 12:18
поделиться

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

SELECT t1.*
FROM mytable t1
  LEFT OUTER JOIN mytable t2
    ON (t1.UserId = t2.UserId AND t1."Date" < t2."Date")
WHERE t2.UserId IS NULL;

, Другими словами: выберите строку от t1, где никакая другая строка не существует с тем же UserId и большая Дата.

(я поместил идентификатор "Дата" в разделители, потому что это - зарезервированное слово SQL.)

В случае, если, если t1."Date" = t2."Date", удвоение появляется. Обычно таблицы имеют auto_inc(seq) ключ, например, id. Постараться не удваиваться может использоваться, следует:

SELECT t1.*
FROM mytable t1
  LEFT OUTER JOIN mytable t2
    ON t1.UserId = t2.UserId AND ((t1."Date" < t2."Date") 
         OR (t1."Date" = t2."Date" AND t1.id < t2.id))
WHERE t2.UserId IS NULL;
<час>

комментарий Ре от @Farhan:

Вот более подробное объяснение:

внешнее объединение пытается присоединиться t1 к t2. По умолчанию все результаты t1 возвращаются, и , если существует соответствие в [1 110], оно также возвращается. Если там не идет ни в какое сравнение в [1 111] с данной строкой [1 112], то запрос все еще возвращает строку [1 113] и использует NULL в качестве заполнителя для всех из [1 115] столбцы. Это, как внешние объединения работают в целом.

прием в этом запросе должен разработать соответствие соединения условию, таким образом, что t2 должен соответствовать тот же userid, и больше date. Идея, являющаяся, если строка существует в [1 119], который имеет большее date, тогда строка в [1 121], она сравнена с [1 138], не может быть самым большим date для этого userid. Но если там не идет ни в какое сравнение - т.е. если никакая строка не существует в [1 124] с большим date, чем строка в [1 126] - мы знаем, что строка в [1 127] была строкой с самым большим date для, учитывая [1 129].

В тех случаях (когда там не будет идти ни в какое сравнение), столбцы t2 будут NULL - даже столбцы, определенные в условии объединения. Так вот почему мы используем WHERE t2.UserId IS NULL, потому что мы ищем случаи, где никакая строка не была найдена с большим date для, учитывая [1 134].

424
ответ дан Juan Castillo 26 March 2017 в 12:18
поделиться

Это также позаботится о дубликатах (возвращает одну строку для каждого user_id):

SELECT *
FROM (
  SELECT u.*, FIRST_VALUE(u.rowid) OVER(PARTITION BY u.user_id ORDER BY u.date DESC) AS last_rowid
  FROM users u
) u2
WHERE u2.rowid = u2.last_rowid
1
ответ дан 22 November 2019 в 22:16
поделиться

Ответ здесь - только Oracle. Вот немного более сложный ответ во всех SQL:

У кого лучший общий результат домашнего задания (максимальная сумма баллов за домашнее задание)?

SELECT FIRST, LAST, SUM(POINTS) AS TOTAL
FROM STUDENTS S, RESULTS R
WHERE S.SID = R.SID AND R.CAT = 'H'
GROUP BY S.SID, FIRST, LAST
HAVING SUM(POINTS) >= ALL (SELECT SUM (POINTS)
FROM RESULTS
WHERE CAT = 'H'
GROUP BY SID)

И более сложный пример, требующий некоторых пояснений, на который у меня нет времени atm:

Укажите книгу (ISBN и название), которая стала самой популярной в 2008 году, т.е. которая чаще всего заимствовалась в 2008 году.

SELECT X.ISBN, X.title, X.loans
FROM (SELECT Book.ISBN, Book.title, count(Loan.dateTimeOut) AS loans
FROM CatalogEntry Book
LEFT JOIN BookOnShelf Copy
ON Book.bookId = Copy.bookId
LEFT JOIN (SELECT * FROM Loan WHERE YEAR(Loan.dateTimeOut) = 2008) Loan 
ON Copy.copyId = Loan.copyId
GROUP BY Book.title) X
HAVING loans >= ALL (SELECT count(Loan.dateTimeOut) AS loans
FROM CatalogEntry Book
LEFT JOIN BookOnShelf Copy
ON Book.bookId = Copy.bookId
LEFT JOIN (SELECT * FROM Loan WHERE YEAR(Loan.dateTimeOut) = 2008) Loan 
ON Copy.copyId = Loan.copyId
GROUP BY Book.title);

Надеюсь, это поможет (кому угодно) ..:)

С уважением, {{ 1}} Гуус

2
ответ дан 22 November 2019 в 22:16
поделиться

Только что протестировал это, и похоже, что он работает с таблицей журналов

select ColumnNames, max(DateColumn) from log  group by ColumnNames order by 1 desc
1
ответ дан 22 November 2019 в 22:16
поделиться

Просто пришлось написать "живой" пример на работе :)

Этот поддерживает несколько значений для UserId на ту же дату.

Колонки: UserId, Value, Date

SELECT
   DISTINCT UserId,
   MAX(Date) OVER (PARTITION BY UserId ORDER BY Date DESC),
   MAX(Values) OVER (PARTITION BY UserId ORDER BY Date DESC)
FROM
(
   SELECT UserId, Date, SUM(Value) As Values
   FROM <<table_name>>
   GROUP BY UserId, Date
)

Вы можете использовать FIRST_VALUE вместо MAX и посмотреть это в плане объяснения. У меня не было времени поиграть с этим.

Конечно, при поиске в огромных таблицах, вероятно, будет лучше, если вы будете использовать FULL подсказки в запросе.

3
ответ дан 22 November 2019 в 22:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: