각 사용자의 최신 레코드 날짜에 대해 sql을 쿼리하려면 어떻게 해야 합니까?
사용자가 로그온한 시간에 대한 컬렉션 항목인 테이블이 있습니다.
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..
각 사용자의 최신 날짜를 알려주는 쿼리를 작성하려면 어떻게 해야 합니까?
업데이트: 최신 날짜와 함께 값이 필요하다는 것을 잊었습니다.
이는 거의 모든 DB 엔진에서 작동하는 단순한 구식 접근 방식이지만 중복에 주의해야 합니다.
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
을 사용하면 된 레코드로 할 수 있는 를 방지할 수 .date
따라서 db엔진이 이를 허용하는 경우 다음과 같은 작업을 수행할 수 있습니다.
select x.username, x.date, x.value
from (
select username, date, value,
row_number() over (partition by username order by date desc) as _rn
from MyTable
) x
where x._rn = 1
윈도 기능 사용(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
대부분의 개발자가 대용량 데이터에 미치는 영향을 고려하지 않고 인라인 쿼리를 사용하는 것으로 보입니다.
간단하게, 다음의 방법으로 이것을 실현할 수 있습니다.
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;
내 경험상 가장 빠른 방법은 테이블에 새로운 행이 없는 각 행을 선택하는 것입니다.
또 다른 장점은 사용되는 구문이 매우 단순하고 쿼리의 의미를 이해하기 쉽다는 것입니다(검토 중인 사용자 이름에 대해 새로운 행이 존재하지 않도록 모든 행을 사용합니다).
존재하지 않는다
SELECT username, value
FROM t
WHERE NOT EXISTS (
SELECT *
FROM t AS witness
WHERE witness.username = t.username AND witness.date > t.date
);
행_번호
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
이너 조인트
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;
좌측 아우터 조인트
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
사용자의 최대 날짜를 포함하는 행 전체를 가져오려면 다음 절차를 수행합니다.
select username, date, value
from tablename where (username, date) in (
select username, max(date) as date
from tablename
group by username
)
SELECT *
FROM MyTable T1
WHERE date = (
SELECT max(date)
FROM MyTable T2
WHERE T1.username=T2.username
)
이것은 당신이 편집한 질문에 대한 정확한 결과를 줄 것입니다.
의 행만 합니다.GROUP BY
넥타이는 알아서 할 거예요.사용자에 됩니다.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
하는 경우 " " " 입니다.TOP 1 WITH TIES
가 되다ROWNUMER
.
입력한 데이터 예시와 함께 다음 쿼리를 사용합니다.
SELECT TOP 1 WITH TIES
username, date, value
FROM user_log_in_attempts
ORDER BY ROW_NUMBER() OVER (PARTITION BY username ORDER BY date DESC)
산출량:
username | date | value
-----------------------------
bob | 8/4/2009 | 1.5
brad | 2/2/2010 | 1.2
fred | 12/2/2009 | 1.3
구조:
ROWNUMBER() OVER (PARTITION BY... ORDER BY...)
각 행 부터 가장 까지 됩니다.ORDER BY ROWNUMBER...
는 각 어린 을 맨 각 두 을 정렬합니다. 하면, 각 사용자의 두 번째 이 정렬됩니다.TOP 1 WITH TIES
각 사용자의 행이 가장 작기 때문에 정렬 기준에서 가장 작은 행은 동일합니다(모두 rownumber=1).이치
SQL-Server에서 테스트 완료.
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
이것은 위의 답변 중 하나와 비슷하지만, 제 생각에는 훨씬 간단하고 깔끔합니다.또한 cross apply 문을 잘 사용합니다.SQL Server 2005 이상일 경우...
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
분석 순위 함수를 사용할 수도 있습니다.
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
SELECT MAX(DATE) AS dates
FROM assignment
JOIN paper_submission_detail ON assignment.PAPER_SUB_ID =
paper_submission_detail.PAPER_SUB_ID
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
업데이트된 문제에 대처합니다.인덱스가 잘 되어도 큰 테이블에서는 잘 동작하지 않을 수 있습니다.
SELECT *
FROM ReportStatus c
inner join ( SELECT
MAX(Date) AS MaxDate
FROM ReportStatus ) m
on c.date = m.maxdate
Oracle의 경우 결과 세트를 내림차순으로 정렬하고 첫 번째 레코드를 가져오면 다음과 같은 최신 레코드를 얻을 수 있습니다.
select * from mytable
where rownum = 1
order by date desc
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
Select * from table1 where lastest_date=(select Max(latest_date) from table1 where user=yourUserName)
내부 쿼리는 현재 사용자의 최신 날짜를 반환하고 외부 쿼리는 내부 쿼리 결과에 따라 모든 데이터를 가져옵니다.
이 방법을 사용하여 테이블에 있는 각 사용자의 마지막 레코드를 가져왔습니다.최근 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
나의 작은 컴필레이션
- 자신
join
둥지보다 낫다select
- 그렇지만
group by
줄 수 없다primary key
어느 쪽이 좋은가 좋다join
- 이 열쇠는 다음에 의해 주어질 수 있다.
partition by
와 함께first_value
(표준)
여기서 질문이 있습니다.
선택한다.t.*부터표 t 내부 결합(고유 first_value 선택()ID) ID 오버(GroupColumn 오더별 DateColumn 설명별 파티션)표에서여기서 FilterColumn = '값') j on t.ID = j.ID
장점:
- 데이터 필터링 방법
where
임의의 컬럼을 사용한 스테이트먼트 select
필터링된 행의 열
단점:
- 2012년부터 MS SQL Server가 필요합니다.
나는 내 응용 프로그램에 대해 다음과 같이 어느 정도 했다.
다음은 쿼리입니다.
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));
다음은 SQL Server의 각 사용자에 대한 최신 레코드만 반환하는 한 가지 방법입니다.
WITH CTE AS (
SELECT *, ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY date DESC) AS rn
FROM your_table
)
SELECT *
FROM CTE
WHERE rn = 1;
이 경우 Common Table Expression(CTE; 공통 테이블식)을 사용하여 user_id에 따라 사용자별로 원하는 rn(행 번호)을 할당하고 날짜별로 내림차순으로 정렬합니다.마지막 쿼리는 rn이 1인 레코드만 선택합니다.이것은 각 사용자의 최신 레코드를 나타냅니다.
SELECT * FROM TABEL1 WHERE DATE= (SELECT MAX(CREATED_DATE) FROM TABEL1)
집계 함수 MAX 및 GROUP BY를 사용합니다.
SELECT username, MAX(date), value FROM tablename GROUP BY username, value
언급URL : https://stackoverflow.com/questions/2411559/how-do-i-query-sql-for-a-latest-record-date-for-each-user
'programing' 카테고리의 다른 글
VBA에서 폼에서 모듈로의 변수 전달 (0) | 2023.04.20 |
---|---|
MVVM에서 ViewModelBase를 쓰는 방법 (0) | 2023.04.20 |
DataGrid의 텍스트 정렬 (0) | 2023.04.20 |
키와 값의 개별 목록에서 사전(딕트)을 만들려면 어떻게 해야 합니까? (0) | 2023.04.20 |
Interop을 사용하여 Excel 파일에서 빈 행과 열을 제거하는 가장 빠른 방법 (0) | 2023.04.20 |