티스토리 뷰
MS-SQL 2005 부터 생긴 ROW_NUMBER() 함수와 비슷한 기능을 mysql에서 구현한 것입니다.
출처 : http://www.explodybits.com/2011/11/mysql-row-number/
Have you ever been in a situation where you are selecting records from a database that need to be ranked, but the column(s) you’re attempting to ORDER BY
are not unique. For example, using the Orders table below, how could you display a distinct list of customers and their last order? The problem is that the date field contains only the date, but not the time. Therefore, it’s possible that two orders can be placed by the same customer on the same day. Now if we had a field defined as AUTO_INCREMENT
in MySQL or IDENTITY
in Microsoft SQL Server and the records were entered sequentially, this would be a simple task.
Orders Table
This can be solved in MS SQL , and with a little more code in MySQL , as well. In MS SQL Server 2005+, uniquely identifying the above records is a breeze using the ROW_NUMBER()
function. If your not familiar withROW_NUMBER()
, MSDN defines theT-SQL ROW_NUMBER()as“Returns the sequential number of a row within a partition of a result set, starting at 1 for the first row in each partition.”
So, in order to display a distinct list of customers and uniquely identify their last order, we could write something like:
Notice how a unique row number is now apparent on each row within the partition. The next step would be to encompasses the statement in a sub query or Common Table Expression (CTE), and filter out the unwanted records based on the generated row number.
The result is a single record for each customer, even when the customer has more than one order on the same day.
MySQL Implementation
Recently, I ran into a similar situation on a WordPress implementation, but with Horses not Orders/Customers. The requirement was to display each horse’s last workout and next race. MySQL does not have a ROW_NUMBER()
function. However, MySQL does allow for inline assignment of variables and the ability to reassign and reference those variables as the query is working its way through the execution. This allows the same functionality thatROW_NUMBER()
provides to be achieved in MySQL. Sticking to the same example used above the MySQL solution would be.
A unique row number is now apparent on each row with in the partition. The @row_num
variable holds the current row number and the @pev_value
variable holds the current value of the partition by field. The variables are defined and assigned a default value with in subqueries. The Orders table and the subqueries are then combined in a single select statement. The @row_num
variable is incremented by one until the @prev_value
does not equal the Customer and is then reset back to one.
Important
- The
@row_num
variable must be set before the@prev_value
variable - The first field in the
ORDER BY
must be the field that you are partitioning by - The default value assigned to the
@prev_value
variable must not exist in the partition by field
As we did with the MS SQL ROW_NUMBER()
example, we will need to encompass the statement in a sub query in order to filter based on the generated row number.
The result is a single record for each customer, even when the customer had more than one order on the same day.
The best solution is to avoid being in this situation in the first place. However an existing data schema does not always lend itself to new requirements.
'Program > DB' 카테고리의 다른 글
mysql 뷰(view), 프로시저(procedure) 내용 확인 (0) | 2016.02.24 |
---|---|
SQL Server 다른 서버에 있는 DB와 연결하기 (1) | 2014.07.24 |
[MSSQL] 날짜연산 DATEADD (1) | 2011.06.20 |
[MSSQL] Datename() 특정요일 가져오기 (0) | 2010.12.11 |
[MSSQL]CONVERT(varchar(20), GETDATE(), number)형식 (0) | 2010.11.22 |
- Total
- Today
- Yesterday
- ASP.NET
- 크루즈
- getdate()
- 웹표준
- 베이커리온유
- 제주고속
- 광령힐식당
- 탐나는전 제주지역화폐
- 남매펜션
- sqlserver
- 동남아크루즈
- SQL
- API
- SQL Server
- 월드드림호
- 제라진돼지국밥
- 한 달 살기
- 제주도
- 솔브레
- 세화갈비
- 요일
- MySQL
- 김녕 바닷길
- 제주동문시장
- MSSQL
- 비자숲힐링센터
- php
- 배낭속크루즈
- 이호테우해수욕장
- 꼬마방앗간
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 |