programing

각 사용자의 최신 레코드 날짜에 대해 sql을 쿼리하려면 어떻게 해야 합니까?

showcode 2023. 4. 20. 23:24
반응형

각 사용자의 최신 레코드 날짜에 대해 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

Demo

구조:

  • 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

반응형