SQL Join: 1대 다 관계에서 마지막 레코드 선택
고객 테이블과 구매 테이블이 있다고 가정해 봅시다.각 구매는 한 명의 고객에게 귀속됩니다.모든 를 한 하고 싶습니다.SELECT. 어떤 방법인가요?스트트 ?? ?? ?? ?? ? ???인인작 성한 ?한? 언? ???
답변에는 다음 표/열 이름을 사용하십시오.
- ★★★★★★★★★★★★★★
id,name - ★★★★★★★
id,customer_id,item_id,date
또한 더 복잡한 상황에서는 마지막으로 구입한 제품을 고객 테이블에 올려 데이터베이스를 정규화하는 것이 (퍼포먼스 면에서) 유리할까요?
(입))의 id할 수 있는데, 이렇게 할 수 요? 문장을 다음과 같은 방법으로 단순화할 수 있습니까?LIMIT 1
이 바로 '하다'의 입니다.greatest-n-per-groupStack Overflow 입니다.
이 문제를 해결하는 방법은 다음과 같습니다.
SELECT c.*, p1.*
FROM customer c
JOIN purchase p1 ON (c.id = p1.customer_id)
LEFT OUTER JOIN purchase p2 ON (c.id = p2.customer_id AND
(p1.date < p2.date OR (p1.date = p2.date AND p1.id < p2.id)))
WHERE p2.id IS NULL;
: 행 : " "p1.p2 및 그의 날짜넥타이의 , 그 의 날짜)를 경우.id 그 이 맞다.p1는 그 고객의 최신 구매품입니다.
purchase columns( ( ( ( ) )customer_id,date,id이렇게 하면 커버링 인덱스를 사용하여 외부 결합을 수행할 수 있습니다.최적화는 구현에 따라 다르므로 반드시 플랫폼에서 테스트하십시오.RDBMS: 예:EXPLAINMySQL my my my my my 。
위에서 설명한 솔루션 대신 서브쿼리를 사용하는 사람도 있지만, 저는 이 솔루션을 통해 관계를 쉽게 해결할 수 있다고 생각합니다.
하위 선택을 사용하여 이 작업을 시도할 수도 있습니다.
SELECT c.*, p.*
FROM customer c INNER JOIN
(
SELECT customer_id,
MAX(date) MaxDate
FROM purchase
GROUP BY customer_id
) MaxDates ON c.id = MaxDates.customer_id INNER JOIN
purchase p ON MaxDates.customer_id = p.customer_id
AND MaxDates.MaxDate = p.date
선택 항목은 모든 고객과 마지막 구매 날짜에 참여해야 합니다.
하나의 은 '먹다'를 입니다.NOT EXISTS가입 조건의 조건을 설정하여 나중에 구입하기 위해 테스트합니다.
SELECT *
FROM customer c
LEFT JOIN purchase p ON (
c.id = p.customer_id
AND NOT EXISTS (
SELECT 1 FROM purchase p1
WHERE p1.customer_id = c.id
AND p1.id > p.id
)
)
Postgre Postgre를 하는 SQL을 사용할 수 .DISTINCT ON그룹 내 첫 번째 행을 찾습니다.
SELECT customer.*, purchase.*
FROM customer
JOIN (
SELECT DISTINCT ON (customer_id) *
FROM purchase
ORDER BY customer_id, date DESC
) purchase ON purchase.customer_id = customer.id
에 주의:DISTINCT ON--여기서 customer_id의 끝.ORDER BY절을 클릭합니다.
경고: 이것은 비표준 조항입니다.
데이터베이스를 지정하지 않았습니다.분석 기능을 사용할 수 있는 경우 GROUP BY 방식보다 이 방식을 사용하는 것이 더 빠를 수 있습니다(Oracle에서는 확실히 더 빠르며 SQL Server 최신 버전에서는 가장 빠를 수 있으며 다른 방법을 알 수 없습니다).
SQL Server의 구문은 다음과 같습니다.
SELECT c.*, p.*
FROM customer c INNER JOIN
(SELECT RANK() OVER (PARTITION BY customer_id ORDER BY date DESC) r, *
FROM purchase) p
ON (c.id = p.customer_id)
WHERE p.r = 1
나는 내 문제의 해결책으로 이 실을 찾았다.
그런데 막상 해보니까 성능이 떨어졌어요.Bellow는 더 나은 성과를 위한 나의 제안이다.
With MaxDates as (
SELECT customer_id,
MAX(date) MaxDate
FROM purchase
GROUP BY customer_id
)
SELECT c.*, M.*
FROM customer c INNER JOIN
MaxDates as M ON c.id = M.customer_id
이것이 도움이 되기를 바랍니다.
이거 드셔보세요, 도움이 될 거예요.
나는 이것을 내 프로젝트에 사용했다.
SELECT
*
FROM
customer c
OUTER APPLY(SELECT top 1 * FROM purchase pi
WHERE pi.customer_id = c.Id order by pi.Id desc) AS [LastPurchasePrice]
SQLite에서 테스트 완료:
SELECT c.*, p.*, max(p.date)
FROM customer c
LEFT OUTER JOIN purchase p
ON c.id = p.customer_id
GROUP BY c.id
그max()aggregate 함수는 각 그룹에서 최신 구매가 선택되었음을 확인합니다(단, date 컬럼은 max()가 최신을 제공하는 형식이라고 가정합니다.일반적으로 이 형식입니다).같은 날짜의 구매를 처리하려면 다음을 사용할 수 있습니다.max(p.date, p.id).
인덱스에 관해서는 구매 시 인덱스를 사용하고 싶습니다(고객 ID, 날짜, 기타 선택하신 구매란).
그LEFT OUTER JOIN(과 반대로)INNER JOIN)는, 구입을 실시하지 않은 고객도 포함한 것을 확인합니다.
SQL Server에서는 다음을 사용할 수 있습니다.
SELECT *
FROM customer c
INNER JOIN purchase p on c.id = p.customer_id
WHERE p.id = (
SELECT TOP 1 p2.id
FROM purchase p2
WHERE p.customer_id = p2.customer_id
ORDER BY date DESC
)
SQL Server Fidle: http://sqlfiddle.com/ #! 18/262g/2
MySQL에서는 다음을 사용할 수 있습니다.
SELECT c.name, date
FROM customer c
INNER JOIN purchase p on c.id = p.customer_id
WHERE p.id = (
SELECT p2.id
FROM purchase p2
WHERE p.customer_id = p2.customer_id
ORDER BY date DESC
LIMIT 1
)
MySQL 바이올린: http://sqlfiddle.com/ #!9/202613/7
몇 년이 지났지만 당신이 필요로 하는 것이 필요했고, 가장 인기 있는 두 가지 답을 시도했다.이것들은 원하는 열매를 맺지 못했다.그래서 이게 내가 제안해야 할...확실히 하기 위해 몇 가지 이름을 바꿨어요.
SELECT
cc.pk_ID AS pk_Customer_ID,
cc.Customer_Name AS Customer_Name,
IFNULL(pp.pk_ID, '') AS fk_Purchase_ID,
IFNULL(pp.fk_Customer_ID, '') AS fk_Customer_ID,
IFNULL(pp.fk_Item_ID, '') AS fk_Item_ID,
IFNULL(pp.Purchase_Date, '') AS Purchase_Date
FROM customer cc
LEFT JOIN purchase pp ON (
SELECT zz.pk_ID
FROM purchase zz
WHERE cc.pk_ID = zz.fk_Customer_ID
ORDER BY zz.Purchase_Date DESC LIMIT 1) = pp.pk_ID
ORDER BY cc.pk_ID;
이거 드셔보세요.
SELECT
c.Id,
c.name,
(SELECT pi.price FROM purchase pi WHERE pi.Id = MAX(p.Id)) AS [LastPurchasePrice]
FROM customer c INNER JOIN purchase p
ON c.Id = p.customerId
GROUP BY c.Id,c.name;
코드를 먼저 입력하지 않고 논리/알고리즘은 다음과 같습니다.
로 이동합니다.
transaction같은 레코드가 여러 개 있는 테이블client.레코드 선택
clientID및 그latestDate클라이언트 액티비티의group by clientID그리고.max(transactionDate)select clientID, max(transactionDate) as latestDate from transaction group by clientIDinner join그transaction스텝 2의 결과를 표로 작성하면, 다음의 모든 기록을 얻을 수 있습니다.transaction테이블에는 각 클라이언트의 최신 레코드만 기재되어 있습니다.select * from transaction t inner join ( select clientID, max(transactionDate) as latestDate from transaction group by clientID) d on t.clientID = d.clientID and t.transactionDate = d.latestDate)순서 3 의 결과를 사용하고, 다른 결과를 얻을 수 있는 임의의 테이블을 결합할 수 있습니다.
표:
Customer => id, name
Purchase => id, customer_id, item_id, date
쿼리:
SELECT C.id, C.name, P.id, P.date
FROM customer AS C
LEFT JOIN purchase AS P ON
(
P.customer_id = C.id
AND P.id IN (
SELECT MAX(PP.id) FROM purchase AS PP GROUP BY PP.customer_id
)
)
또, 다음의 몇개의 조건을 지정할 수도 있습니다.sub select질문하다
언급URL : https://stackoverflow.com/questions/2111384/sql-join-selecting-the-last-records-in-a-one-to-many-relationship
'programing' 카테고리의 다른 글
| iPhone의 내비게이션 바에서 '뒤로' 버튼을 숨기는 방법 (0) | 2023.04.14 |
|---|---|
| Excel에서 시간 필드를 문자열로 변환 (0) | 2023.04.14 |
| Excel로의 JSON Import (0) | 2023.04.14 |
| 변수를 소스 없이 Bash 스크립트에서 환경으로 내보낼 수 있습니까? (0) | 2023.04.14 |
| PowerShell의 *Nix 'which' 명령어와 동등합니까? (0) | 2023.04.14 |