С 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"
Это получит все строки, для которых 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 от первой строки в разделе к текущему"
, пункт работы с окнами только применим в присутствии порядка пунктом. Без порядка пунктом никакой пункт работы с окнами не применяется по умолчанию, и ни один не может быть явно определен.
работы кода.
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
Я думаю, что это должно работать?
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
Сначала попробуйте, я неправильно читал вопрос, после главного ответа, вот полный пример с корректными результатами:
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)
Это должно быть столь же просто как:
SELECT UserId, Value
FROM Users u
WHERE Date = (SELECT MAX(Date) FROM Users WHERE UserID = u.UserID)
Принятие Даты уникально для данного 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
Если (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;
Я думаю что-то вроде этого. (Простите мне за любые ошибки синтаксиса; я привык использовать HQL в этой точке!)
РЕДАКТИРОВАНИЕ: Также неправильно читайте вопрос! Исправленный запрос...
SELECT UserId, Value
FROM Users AS user
WHERE Date = (
SELECT MAX(Date)
FROM Users AS maxtest
WHERE maxtest.UserId = user.UserId
)
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
(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
я вещь Вы shuold делаю этот вариант к предыдущему запросу:
SELECT UserId, Value FROM Users U1 WHERE
Date = ( SELECT MAX(Date) FROM Users where UserId = U1.UserId)
У меня нет 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...)
Я знаю, что Вы попросили 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
Я не знаю Ваши точные названия столбцов, но это было бы что-то вроде этого:
select userid, value from users u1 where date = (select max(date) from users u2 where u1.userid = u2.userid)
Не работать, у меня нет 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 материала, упомянутого в другом месте, может быть более производительной.
SELECT userid, MAX(value) KEEP (DENSE_RANK FIRST ORDER BY date DESC)
FROM table
GROUP BY userid
Я вижу, что многие люди используют подзапросы или иначе определенные для поставщика функции, чтобы сделать это, но я часто делаю этот вид запроса без подзапросов следующим образом. Это использует плоскость, стандартный 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].
Это также позаботится о дубликатах (возвращает одну строку для каждого 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
Ответ здесь - только 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}} Гуус
Только что протестировал это, и похоже, что он работает с таблицей журналов
select ColumnNames, max(DateColumn) from log group by ColumnNames order by 1 desc
Просто пришлось написать "живой" пример на работе :)
Этот поддерживает несколько значений для 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 подсказки в запросе.