jak odpytywać sql o najnowszą datę rekordu dla każdego użytkownika
Mam tabelę, która jest zbiorem wpisów, kiedy użytkownik był zalogowany.
username, date, value
--------------------------
brad, 1/2/2010, 1.1
fred, 1/3/2010, 1.0
bob, 8/4/2009, 1.5
brad, 2/2/2010, 1.2
fred, 12/2/2009, 1.3
etc..
Jak utworzyć zapytanie, które poda mi najnowszą datę dla każdego użytkownika?
Update: zapomniałem, że muszę mieć wartość, która pasuje do ostatniej daty.
21 answers
select t.username, t.date, t.value
from MyTable t
inner join (
select username, max(date) as MaxDate
from MyTable
group by username
) tm on t.username = tm.username and t.date = tm.MaxDate
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-09 18:56:12
Korzystanie z funkcji okien (działa w Oracle, Postgres 8.4, SQL Server 2005, DB2, Sybase, Firebird 3.0, MariaDB 10.3)
select * from (
select
username,
date,
value,
row_number() over(partition by username order by date desc) as rn
from
yourtable
) t
where t.rn = 1
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-27 06:20:45
Widzę, że większość programistów używa zapytania inline, nie biorąc pod uwagę jego wpływu na ogromne dane.
Po prostu możesz to osiągnąć poprzez:
SELECT a.username, a.date, a.value
FROM myTable a
LEFT OUTER JOIN myTable b
ON a.username = b.username
AND a.date < b.date
WHERE b.username IS NULL
ORDER BY a.date desc;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-02 01:31:31
Aby uzyskać cały wiersz zawierający maksymalną datę dla użytkownika:
select username, date, value
from tablename where (username, date) in (
select username, max(date) as date
from tablename
group by username
)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-09 18:54:15
SELECT *
FROM MyTable T1
WHERE date = (
SELECT max(date)
FROM MyTable T2
WHERE T1.username=T2.username
)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-03 14:18:46
Ten powinien dać ci poprawny wynik dla edytowanego pytania.
Pod-zapytanie upewnia się, że znajdzie tylko wiersze ostatniej daty, A zewnętrzne GROUP BY
zajmie się powiązaniami. Jeśli istnieją dwa wpisy dla tego samego dnia dla tego samego użytkownika, zwróci on ten z najwyższą value
.
SELECT t.username, t.date, MAX( t.value ) value
FROM your_table t
JOIN (
SELECT username, MAX( date ) date
FROM your_table
GROUP BY username
) x ON ( x.username = t.username AND x.date = t.date )
GROUP BY t.username, t.date
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-09 18:54:11
Dla Oracle sortuje wynik ustawiony w porządku malejącym i pobiera pierwszy rekord, więc otrzymasz najnowszy rekord:
select * from mytable
where rownum = 1
order by date desc
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-05 19:51:17
SELECT * FROM TABEL1 WHERE DATE= (SELECT MAX(CREATED_DATE) FROM TABEL1)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-29 12:02:29
SELECT Username, date, value
from MyTable mt
inner join (select username, max(date) date
from MyTable
group by username) sub
on sub.username = mt.username
and sub.date = mt.date
Rozwiązuje zaktualizowany problem. Może to nie działać tak dobrze na dużych stołach, nawet przy dobrym indeksowaniu.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-09 18:53:52
SELECT *
FROM ReportStatus c
inner join ( SELECT
MAX(Date) AS MaxDate
FROM ReportStatus ) m
on c.date = m.maxdate
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-18 11:13:01
SELECT t1.username, t1.date, value
FROM MyTable as t1
INNER JOIN (SELECT username, MAX(date)
FROM MyTable
GROUP BY username) as t2 ON t2.username = t1.username AND t2.date = t1.date
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-27 15:34:39
Select * from table1 where lastest_date=(select Max(latest_date) from table1 where user=yourUserName)
Zapytanie wewnętrzne zwróci ostatnią datę dla bieżącego użytkownika, zapytanie zewnętrzne pobierze wszystkie dane zgodnie z wynikiem zapytania wewnętrznego.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-04 10:12:54
Użyłem tego sposobu, aby pobrać ostatni rekord dla każdego użytkownika, który mam na stole. Było to zapytanie, aby uzyskać ostatnią lokalizację sprzedawcy, zgodnie z ostatnim czasem wykrytym na urządzeniach PDA.
CREATE FUNCTION dbo.UsersLocation()
RETURNS TABLE
AS
RETURN
Select GS.UserID, MAX(GS.UTCDateTime) 'LastDate'
From USERGPS GS
where year(GS.UTCDateTime) = YEAR(GETDATE())
Group By GS.UserID
GO
select gs.UserID, sl.LastDate, gs.Latitude , gs.Longitude
from USERGPS gs
inner join USER s on gs.SalesManNo = s.SalesmanNo
inner join dbo.UsersLocation() sl on gs.UserID= sl.UserID and gs.UTCDateTime = sl.LastDate
order by LastDate desc
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-27 14:39:57
Moja mała kompilacja
- self
join
better than nestedselect
- Ale
group by
nie dajeprimary key
co jest lepsze dlajoin
- klucz ten może być podany przez
partition by
w połączeniu zfirst_value
(docs )
Oto zapytanie:
select t.* from Table t inner join ( select distinct first_value(ID) over(partition by GroupColumn order by DateColumn desc) as ID from Table where FilterColumn = 'value' ) j on t.ID = j.ID
Plusy:
- Filtruj dane za pomocą instrukcji
where
używając dowolnej kolumny -
select
dowolne kolumny z przefiltrowanych wierszy
Wady:
- Need MS SQL Serwer od 2012 roku.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-23 05:24:42
Zrobiłem trochę dla mojej aplikacji jak to:
Poniżej znajduje się zapytanie:
select distinct i.userId,i.statusCheck, l.userName from internetstatus
as i inner join login as l on i.userID=l.userID
where nowtime in((select max(nowtime) from InternetStatus group by userID));
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-07 12:16:37
Z mojego doświadczenia wynika, że najszybszym sposobem jest pobranie każdego wiersza, dla którego nie ma nowszego wiersza w tabeli. Oto mały benchmark z niektórymi danymi, które mam pod ręką.
Kolejną zaletą jest to, że używana składnia jest bardzo prosta i że znaczenie zapytania jest dość łatwe do zrozumienia(weź wszystkie wiersze tak, że nie ma nowszego wiersza dla nazwy użytkownika, która jest brana pod uwagę).
NIE ISTNIEJE
SELECT username, value
FROM t
WHERE NOT EXISTS (
SELECT *
FROM t AS witness
WHERE witness.date > t.date
);
Wyjaśnij całkowity koszt : 2.38136
ROW_NUMBER
SELECT username, value
FROM (
SELECT username, value, row_number() OVER (PARTITION BY username ORDER BY date DESC) AS rn
FROM t
) t2
WHERE rn = 1
Całkowity koszt : 61.5823
INNER JOIN
SELECT t.username, t.value
FROM t
INNER JOIN (
SELECT username, MAX(date) AS date
FROM t
GROUP BY username
) tm ON t.username = tm.username AND t.date = tm.date;
Wyjaśnij całkowity koszt : 67.5439
LEFT OUTER JOIN
SELECT username, value
FROM t
LEFT OUTER JOIN t AS w ON t.username = w.username AND t.date < w.date
WHERE w.username IS NULL
Wyjaśnij całkowity koszt : 62.964
Plany wyjaśnień pochodzą z bazy danych zawierającej około 10 tysięcy wierszy, zapisanych jako XML. Używane zapytania zawierają również predykat "group_id = '1'".
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-22 12:36:47
Jest to podobne do jednej z powyższych odpowiedzi, ale moim zdaniem jest o wiele prostsze i bardziej uporządkowane. Ponadto, pokazuje dobre wykorzystanie cross apply oświadczenie. Dla SQL Server 2005 i nowszych...
select
a.username,
a.date,
a.value,
from yourtable a
cross apply (select max(date) 'maxdate' from yourtable a1 where a.username=a1.username) b
where a.date=b.maxdate
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-27 05:16:35
Można również użyć funkcji Rank analityczny
with temp as
(
select username, date, RANK() over (partition by username order by date desc) as rnk from t
)
select username, rnk from t where rnk = 1
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-26 01:42:15
Można użyć funkcji zbiorczej MAX i GROUP BY
SELECT username, MAX(date), value FROM tablename GROUP BY username, value
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-09 18:52:14
SELECT DISTINCT Username, Dates,value
FROM TableName
WHERE Dates IN (SELECT MAX(Dates) FROM TableName GROUP BY Username)
Username Dates value
bob 2010-02-02 1.2
brad 2010-01-02 1.1
fred 2010-01-03 1.0
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-27 13:46:59
Powinno to również działać, aby uzyskać wszystkie najnowsze wpisy dla użytkowników.
SELECT username, MAX(date) as Date, value
FROM MyTable
GROUP BY username, value
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-04 13:41:44