[SQL] 어떻게 SQL의 다른 열을 기준으로 DISTINCT MAX (열 값)와 행을 선택할 수 있습니까?
SQL어떻게 SQL의 다른 열을 기준으로 DISTINCT MAX (열 값)와 행을 선택할 수 있습니까?
내 표는 다음과 같습니다
id home datetime player resource
---|-----|------------|--------|---------
1 | 10 | 04/03/2009 | john | 399
2 | 11 | 04/03/2009 | juliet | 244
5 | 12 | 04/03/2009 | borat | 555
3 | 10 | 03/03/2009 | john | 300
4 | 11 | 03/03/2009 | juliet | 200
6 | 12 | 03/03/2009 | borat | 500
7 | 13 | 24/12/2008 | borat | 600
8 | 13 | 01/01/2009 | borat | 700
나는 날짜의 최대 값을 잡고 각각 별개의 가정을 선택해야합니다.
것입니다 결과 :
id home datetime player resource
---|-----|------------|--------|---------
1 | 10 | 04/03/2009 | john | 399
2 | 11 | 04/03/2009 | juliet | 244
5 | 12 | 04/03/2009 | borat | 555
8 | 13 | 01/01/2009 | borat | 700
나는 시도했다 :
-- 1 ..by the MySQL manual:
SELECT DISTINCT
home,
id,
datetime AS dt,
player,
resource
FROM topten t1
WHERE datetime = (SELECT
MAX(t2.datetime)
FROM topten t2
GROUP BY home)
GROUP BY datetime
ORDER BY datetime DESC
작동하지 않습니다. 데이터베이스 (187)를 보유하고 있지만, 결과 세트 (130 개)의 행을 갖는다. 결과는 가정의 일부 중복이 포함되어 있습니다.
-- 2 ..join
SELECT
s1.id,
s1.home,
s1.datetime,
s1.player,
s1.resource
FROM topten s1
JOIN (SELECT
id,
MAX(datetime) AS dt
FROM topten
GROUP BY id) AS s2
ON s1.id = s2.id
ORDER BY datetime
아니. 모든 레코드를 제공합니다.
-- 3 ..something exotic:
다양한 결과.
해결법
-
==============================
1.당신은 너무 가까이! 당신이해야 할 일은 다음, 가정과의 최대 날짜 시간을 모두 선택 두 필드에 topten 테이블로 다시 조인 :
당신은 너무 가까이! 당신이해야 할 일은 다음, 가정과의 최대 날짜 시간을 모두 선택 두 필드에 topten 테이블로 다시 조인 :
SELECT tt.* FROM topten tt INNER JOIN (SELECT home, MAX(datetime) AS MaxDateTime FROM topten GROUP BY home) groupedtt ON tt.home = groupedtt.home AND tt.datetime = groupedtt.MaxDateTime
-
==============================
2.내부 쿼리없이 GROUP BY없이 가장 빠른 MySQL의 솔루션 :
내부 쿼리없이 GROUP BY없이 가장 빠른 MySQL의 솔루션 :
SELECT m.* -- get the row that contains the max value FROM topten m -- "m" from "max" LEFT JOIN topten b -- "b" from "bigger" ON m.home = b.home -- match "max" row with "bigger" row by `home` AND m.datetime < b.datetime -- want "bigger" than "max" WHERE b.datetime IS NULL -- keep only if there is no bigger than max
설명:
자체가 집에 열을 사용하여 테이블에 가입하세요. LEFT의 사용 보장하지만 모든 테이블 m에서 행 결과 세트에 나타 가입. 표 B에 일치하지 않는 사람은 B의 컬럼에 대해 널 (NULL)이있을 것이다.
조인의 다른 조건은 m 행의 행보다 날짜 열상에서 큰 값이 B의 행과 일치하도록 요청한다.
질문에 게시 된 데이터를 사용하여, 왼쪽은 가입이 쌍을 생성합니다 :
+------------------------------------------+--------------------------------+ | the row from `m` | the matching row from `b` | |------------------------------------------|--------------------------------| | id home datetime player resource | id home datetime ... | |----|-----|------------|--------|---------|------|------|------------|-----| | 1 | 10 | 04/03/2009 | john | 399 | NULL | NULL | NULL | ... | * | 2 | 11 | 04/03/2009 | juliet | 244 | NULL | NULL | NULL | ... | * | 5 | 12 | 04/03/2009 | borat | 555 | NULL | NULL | NULL | ... | * | 3 | 10 | 03/03/2009 | john | 300 | 1 | 10 | 04/03/2009 | ... | | 4 | 11 | 03/03/2009 | juliet | 200 | 2 | 11 | 04/03/2009 | ... | | 6 | 12 | 03/03/2009 | borat | 500 | 5 | 12 | 04/03/2009 | ... | | 7 | 13 | 24/12/2008 | borat | 600 | 8 | 13 | 01/01/2009 | ... | | 8 | 13 | 01/01/2009 | borat | 700 | NULL | NULL | NULL | ... | * +------------------------------------------+--------------------------------+
마지막으로, 절 (B)의 열에서의 널 (NULL) (그들 위의 테이블에서 *로 표시된다)가 단지 한 쌍을 유지하는 곳; 인해에서 두 번째 조건이 수단은, 절 조인 m에서 선택된 행 날짜 열에서 가장 큰 값을 갖는다.
은 SQL 안티 패턴을 읽어 다른 SQL 팁에 대한 데이터베이스 프로그래밍 책의 함정을 피하는.
-
==============================
3.여기에 T-SQL 버전을 간다 :
여기에 T-SQL 버전을 간다 :
-- Test data DECLARE @TestTable TABLE (id INT, home INT, date DATETIME, player VARCHAR(20), resource INT) INSERT INTO @TestTable SELECT 1, 10, '2009-03-04', 'john', 399 UNION SELECT 2, 11, '2009-03-04', 'juliet', 244 UNION SELECT 5, 12, '2009-03-04', 'borat', 555 UNION SELECT 3, 10, '2009-03-03', 'john', 300 UNION SELECT 4, 11, '2009-03-03', 'juliet', 200 UNION SELECT 6, 12, '2009-03-03', 'borat', 500 UNION SELECT 7, 13, '2008-12-24', 'borat', 600 UNION SELECT 8, 13, '2009-01-01', 'borat', 700 -- Answer SELECT id, home, date, player, resource FROM (SELECT id, home, date, player, resource, RANK() OVER (PARTITION BY home ORDER BY date DESC) N FROM @TestTable )M WHERE N = 1 -- and if you really want only home with max date SELECT T.id, T.home, T.date, T.player, T.resource FROM @TestTable T INNER JOIN ( SELECT TI.id, TI.home, TI.date, RANK() OVER (PARTITION BY TI.home ORDER BY TI.date) N FROM @TestTable TI WHERE TI.date IN (SELECT MAX(TM.date) FROM @TestTable TM) )TJ ON TJ.N = 1 AND T.id = TJ.id
편집하다 불행하게도, MySQL은 더 RANK () OVER 기능이 없습니다. 그러나 그것은 (일명 순위) Emulation 소프트웨어 분석의 MySQL과 기능을 참조 에뮬레이트 할 수 있습니다. 이 그래서 MySQL 버전입니다 :
SELECT id, home, date, player, resource FROM TestTable AS t1 WHERE (SELECT COUNT(*) FROM TestTable AS t2 WHERE t2.home = t1.home AND t2.date > t1.date ) = 0
-
==============================
4.당신이 동일한 DATETIME의 각 가정을위한 두 개 이상의 행이있을 경우에도이 작동합니다 :
당신이 동일한 DATETIME의 각 가정을위한 두 개 이상의 행이있을 경우에도이 작동합니다 :
SELECT id, home, datetime, player, resource FROM ( SELECT ( SELECT id FROM topten ti WHERE ti.home = t1.home ORDER BY ti.datetime DESC LIMIT 1 ) lid FROM ( SELECT DISTINCT home FROM topten ) t1 ) ro, topten t2 WHERE t2.id = ro.lid
-
==============================
5.나는이 당신에게 원하는 결과를 줄 것이라고 생각 :
나는이 당신에게 원하는 결과를 줄 것이라고 생각 :
SELECT home, MAX(datetime) FROM my_table GROUP BY home
하지만 당신은뿐만 아니라 다른 열을 필요로하는 경우, 단지 원래 테이블과 조인하게 (마이클 라 Voie 응답을 확인)
친애하는.
-
==============================
6.명 (코멘트 기간이 1.5 년 범위)이 thread로 계속 실행하는 것 때문에이 훨씬 더 간단이되지 않습니다 :
명 (코멘트 기간이 1.5 년 범위)이 thread로 계속 실행하는 것 때문에이 훨씬 더 간단이되지 않습니다 :
(날짜 DESC BY topten ORDER SELECT * FROM) SELECT * FROM 홈페이지 TMP GROUP
없음 집계 함수가 필요하지 ...
건배.
-
==============================
7.당신은이 일을 시도 할 수와 큰 테이블 쿼리 성능을 위해 더 좋을 것이다. 더 이상이 개 각 가정을위한 기록과 날짜가 다를 때 그것은 작동하지 않습니다. 더 나은 일반적으로 MySQL의 쿼리는 위의 마이클 라 Voie에서 하나입니다.
당신은이 일을 시도 할 수와 큰 테이블 쿼리 성능을 위해 더 좋을 것이다. 더 이상이 개 각 가정을위한 기록과 날짜가 다를 때 그것은 작동하지 않습니다. 더 나은 일반적으로 MySQL의 쿼리는 위의 마이클 라 Voie에서 하나입니다.
SELECT t1.id, t1.home, t1.date, t1.player, t1.resource FROM t_scores_1 t1 INNER JOIN t_scores_1 t2 ON t1.home = t2.home WHERE t1.date > t2.date
또는 포스트 그레스 또는 그 DBS의 경우 분석 기능을 시도 제공하는
SELECT t.* FROM (SELECT t1.id, t1.home, t1.date, t1.player, t1.resource , row_number() over (partition by t1.home order by t1.date desc) rw FROM topten t1 INNER JOIN topten t2 ON t1.home = t2.home WHERE t1.date > t2.date ) t WHERE t.rw = 1
-
==============================
8.이것은 오라클에서 작동합니다 :
이것은 오라클에서 작동합니다 :
with table_max as( select id , home , datetime , player , resource , max(home) over (partition by home) maxhome from table ) select id , home , datetime , player , resource from table_max where home = maxhome
-
==============================
9.
SELECT tt.* FROM TestTable tt INNER JOIN ( SELECT coord, MAX(datetime) AS MaxDateTime FROM rapsa GROUP BY krd ) groupedtt ON tt.coord = groupedtt.coord AND tt.datetime = groupedtt.MaxDateTime
-
==============================
10.SQL Server에 대한이 시도 :
SQL Server에 대한이 시도 :
WITH cte AS ( SELECT home, MAX(year) AS year FROM Table1 GROUP BY home ) SELECT * FROM Table1 a INNER JOIN cte ON a.home = cte.home AND a.year = cte.year
-
==============================
11.
SELECT c1, c2, c3, c4, c5 FROM table1 WHERE c3 = (select max(c3) from table) SELECT * FROM table1 WHERE c3 = (select max(c3) from table1)
-
==============================
12.여기에 그룹의 MAX (날짜) 복제가 하나의 항목을 인쇄 MySQL 버전입니다.
여기에 그룹의 MAX (날짜) 복제가 하나의 항목을 인쇄 MySQL 버전입니다.
여기 http://www.sqlfiddle.com/#!2/0a4ae/1 테스트 할 수
mysql> SELECT * from topten; +------+------+---------------------+--------+----------+ | id | home | datetime | player | resource | +------+------+---------------------+--------+----------+ | 1 | 10 | 2009-04-03 00:00:00 | john | 399 | | 2 | 11 | 2009-04-03 00:00:00 | juliet | 244 | | 3 | 10 | 2009-03-03 00:00:00 | john | 300 | | 4 | 11 | 2009-03-03 00:00:00 | juliet | 200 | | 5 | 12 | 2009-04-03 00:00:00 | borat | 555 | | 6 | 12 | 2009-03-03 00:00:00 | borat | 500 | | 7 | 13 | 2008-12-24 00:00:00 | borat | 600 | | 8 | 13 | 2009-01-01 00:00:00 | borat | 700 | | 9 | 10 | 2009-04-03 00:00:00 | borat | 700 | | 10 | 11 | 2009-04-03 00:00:00 | borat | 700 | | 12 | 12 | 2009-04-03 00:00:00 | borat | 700 | +------+------+---------------------+--------+----------+
SELECT * FROM ( SELECT ord.*, IF (@prev_home = ord.home, 0, 1) AS is_first_appear, @prev_home := ord.home FROM ( SELECT t1.id, t1.home, t1.player, t1.resource FROM topten t1 INNER JOIN ( SELECT home, MAX(datetime) AS mx_dt FROM topten GROUP BY home ) x ON t1.home = x.home AND t1.datetime = x.mx_dt ORDER BY home ) ord, (SELECT @prev_home := 0, @seq := 0) init ) y WHERE is_first_appear = 1; +------+------+--------+----------+-----------------+------------------------+ | id | home | player | resource | is_first_appear | @prev_home := ord.home | +------+------+--------+----------+-----------------+------------------------+ | 9 | 10 | borat | 700 | 1 | 10 | | 10 | 11 | borat | 700 | 1 | 11 | | 12 | 12 | borat | 700 | 1 | 12 | | 8 | 13 | borat | 700 | 1 | 13 | +------+------+--------+----------+-----------------+------------------------+ 4 rows in set (0.00 sec)
SELECT tt.* FROM topten tt INNER JOIN ( SELECT home, MAX(datetime) AS MaxDateTime FROM topten GROUP BY home ) groupedtt ON tt.home = groupedtt.home AND tt.datetime = groupedtt.MaxDateTime +------+------+---------------------+--------+----------+ | id | home | datetime | player | resource | +------+------+---------------------+--------+----------+ | 1 | 10 | 2009-04-03 00:00:00 | john | 399 | | 2 | 11 | 2009-04-03 00:00:00 | juliet | 244 | | 5 | 12 | 2009-04-03 00:00:00 | borat | 555 | | 8 | 13 | 2009-01-01 00:00:00 | borat | 700 | | 9 | 10 | 2009-04-03 00:00:00 | borat | 700 | | 10 | 11 | 2009-04-03 00:00:00 | borat | 700 | | 12 | 12 | 2009-04-03 00:00:00 | borat | 700 | +------+------+---------------------+--------+----------+ 7 rows in set (0.00 sec)
-
==============================
13.기본적으로 순위 = 1로 가장 최근의 행을 필터링 한 후 그룹별로 각 행에 대한 순위를 계산하고 하위 쿼리를 사용하여 그룹별로 가장 최근의 행을 GT는 또 다른 방법
기본적으로 순위 = 1로 가장 최근의 행을 필터링 한 후 그룹별로 각 행에 대한 순위를 계산하고 하위 쿼리를 사용하여 그룹별로 가장 최근의 행을 GT는 또 다른 방법
select a.* from topten a where ( select count(*) from topten b where a.home = b.home and a.`datetime` < b.`datetime` ) +1 = 1
데모
여기에 더 나은 이해를 위해 각 행에 대한 순위를 나타내는 시각적 데모는 없다
쿼리보다도 실패하고 위의 상황에 1 개 이상의 행을 반환합니다. 이 상황을 은폐하기 위해 위의 상황에서 떨어지는 촬영해야하는 행을 결정하는 또 다른 기준 / 매개 변수 / 열 필요가있을 것입니다. 보면 샘플 데이터 나 자동 증가 설정해야 기본 키 열 ID가 가정 설정. 우리는 CASE 문의 도움 등으로 같은 쿼리를 조정하여 가장 최근의 행을 선택하는이 열을 사용할 수 있도록
select a.* from topten a where ( select count(*) from topten b where a.home = b.home and case when a.`datetime` = b.`datetime` then a.id < b.id else a.`datetime` < b.`datetime` end ) + 1 = 1
데모
위 쿼리는 같은 날짜 값 중 가장 높은 ID를 가진 행을 선택합니다
각 행의 순위없는 시각적 데모
-
==============================
14.이 시도
이 시도
select * from mytable a join (select home, max(datetime) datetime from mytable group by home) b on a.home = b.home and a.datetime = b.datetime
문안 인사 케이
-
==============================
15.왜 사용하지은 : SELECT 집, MAX (날짜 시간) AS MaxDateTime, 플레이어, 홈 BY topten 그룹에서 자원 내가 뭐 놓친 거 없니?
왜 사용하지은 : SELECT 집, MAX (날짜 시간) AS MaxDateTime, 플레이어, 홈 BY topten 그룹에서 자원 내가 뭐 놓친 거 없니?
-
==============================
16.이것은 당신이 필요로하는 쿼리입니다 :
이것은 당신이 필요로하는 쿼리입니다 :
SELECT b.id, a.home,b.[datetime],b.player,a.resource FROM (SELECT home,MAX(resource) AS resource FROM tbl_1 GROUP BY home) AS a LEFT JOIN (SELECT id,home,[datetime],player,resource FROM tbl_1) AS b ON a.resource = b.resource WHERE a.home =b.home;
-
==============================
17.@Michae는 대답은 대부분의 경우 잘 작동합니다 가능하지만 아래와 같이 하나 실패.
@Michae는 대답은 대부분의 경우 잘 작동합니다 가능하지만 아래와 같이 하나 실패.
경우에는 다음과 같이 쿼리에 고유 추가하는 것이 모두 행, 필요없는 별개의 HomeID을 반환합니다 HomeID 및 날짜 시간 같은 쿼리를 가진 2 개 행이 있다면.
SELECT DISTINCT tt.home , tt.MaxDateTime FROM topten tt INNER JOIN (SELECT home, MAX(datetime) AS MaxDateTime FROM topten GROUP BY home) groupedtt ON tt.home = groupedtt.home AND tt.datetime = groupedtt.MaxDateTime
-
==============================
18.쿼리 아래의 희망은 원하는 출력을 줄 것이다 :
쿼리 아래의 희망은 원하는 출력을 줄 것이다 :
Select id, home,datetime,player,resource, row_number() over (Partition by home ORDER by datetime desc) as rownum from tablename where rownum=1
from https://stackoverflow.com/questions/612231/how-can-i-select-rows-with-maxcolumn-value-distinct-by-another-column-in-sql by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] 어떻게 업데이트는 SQL Server에서 SELECT에서합니까? (0) | 2020.03.05 |
---|---|
[SQL] SQL 주입을 방지하는 좋은 방법은 무엇입니까? [복제] (0) | 2020.03.05 |
[SQL] 나는 하나 개의 필드에 여러 개의 MySQL의 행을 연결할 수 있습니까? (0) | 2020.03.05 |
[SQL] 나무에 평평한 테이블을 구문 분석하는 가장 효율적인 / 우아한 방법은 무엇입니까? (0) | 2020.03.05 |
[SQL] INNER가, 왼쪽, 오른쪽 조인 및 FULL은 조인의 차이점은 무엇입니까? [복제] (0) | 2020.03.05 |