[SQL] SQL 서버 : 어떻게 첫 번째 행에 가입하세요
SQLSQL 서버 : 어떻게 첫 번째 행에 가입하세요
나는 콘크리트,하지만 가상의 예를 사용합니다.
각각의 주문은 일반적으로 하나의 라인 항목이 있습니다 :
명령:
OrderGUID OrderNumber
========= ============
{FFB2...} STL-7442-1
{3EC6...} MPT-9931-8A
LineItems :
LineItemGUID Order ID Quantity Description
============ ======== ======== =================================
{098FBE3...} 1 7 prefabulated amulite
{1609B09...} 2 32 spurving bearing
그러나 때때로이 개 광고 항목 순서가있을 것입니다 :
LineItemID Order ID Quantity Description
========== ======== ======== =================================
{A58A1...} 6,784,329 5 pentametric fan
{0E9BC...} 6,784,329 5 differential girdlespring
일반적으로 사용자에게 주문을 보여줄 때 :
SELECT Orders.OrderNumber, LineItems.Quantity, LineItems.Description
FROM Orders
INNER JOIN LineItems
ON Orders.OrderID = LineItems.OrderID
나는 순서에 단일 항목을 보여주고 싶어요. 그러나이 가끔 순서가 항목을 두를 포함하는 (또는 그 이상)과 함께 주문이 중복 될 나타날 것입니다 :
OrderNumber Quantity Description
=========== ======== ====================
STL-7442-1 7 prefabulated amulite
MPT-9931-8A 32 spurving bearing
KSG-0619-81 5 panametric fan
KSG-0619-81 5 differential girdlespring
내가 진정으로 원하는 것은 충분한 것으로 SQL 서버는 단지 하나를 선택하는 것입니다 :
OrderNumber Quantity Description
=========== ======== ====================
STL-7442-1 7 prefabulated amulite
MPT-9931-8A 32 differential girdlespring
KSG-0619-81 5 panametric fan
나는 모험을 얻는 경우에, 나는보다 더있어 것을 나타 내기 위해서 (때문에), 줄임표를 사용자에게 표시 할 수 있습니다 :
OrderNumber Quantity Description
=========== ======== ====================
STL-7442-1 7 prefabulated amulite
MPT-9931-8A 32 differential girdlespring
KSG-0619-81 5 panametric fan, ...
문제는 방법 중 하나에 그래서
내 첫 순진 시도는 단지 "TOP 1"라인 항목에 가입했다 :
SELECT Orders.OrderNumber, LineItems.Quantity, LineItems.Description
FROM Orders
INNER JOIN (
SELECT TOP 1 LineItems.Quantity, LineItems.Description
FROM LineItems
WHERE LineItems.OrderID = Orders.OrderID) LineItems2
ON 1=1
하지만 그 오류를 제공합니다 :
아마도 내부를 선택하기 때문에 외부 테이블이 표시되지 않습니다.
해결법
-
==============================
1.
SELECT Orders.OrderNumber, LineItems.Quantity, LineItems.Description FROM Orders JOIN LineItems ON LineItems.LineItemGUID = ( SELECT TOP 1 LineItemGUID FROM LineItems WHERE OrderID = Orders.OrderID )
위의 SQL 서버 2005에서는, 당신은 단지 INNER을 대체 할 수있는 적용 CROSS에 가입 :
SELECT Orders.OrderNumber, LineItems2.Quantity, LineItems2.Description FROM Orders CROSS APPLY ( SELECT TOP 1 LineItems.Quantity, LineItems.Description FROM LineItems WHERE LineItems.OrderID = Orders.OrderID ) LineItems2
이 쿼리는 당신에게 주문 당 한 줄의 항목을 얻을 것이다, 그러나 하나가 될 것이다 정의되지 않은 : 참고 ORDER BY없이 TOP 1은 결정되지하시기 바랍니다.
쿼리의 다중 호출은 기본이 변경되지 않은 경우에도 같은 순서로 당신에게 다른 광고 항목에 제공 할 수 있습니다.
당신이 결정 주문을하려는 경우, 당신은 가장 안쪽 쿼리에 ORDER BY 절을 추가해야합니다.
-
==============================
2.나는이 질문에 얼마 전에 대답했다 알지만, 대용량 데이터 세트를 처리 할 때, 중첩 된 쿼리는 비용이 많이들 수 있습니다. 여기에 대신 각 행이 반환을 위해의 중첩 된 쿼리가 한 번만 실행 된 것입니다 다른 솔루션이다.
나는이 질문에 얼마 전에 대답했다 알지만, 대용량 데이터 세트를 처리 할 때, 중첩 된 쿼리는 비용이 많이들 수 있습니다. 여기에 대신 각 행이 반환을 위해의 중첩 된 쿼리가 한 번만 실행 된 것입니다 다른 솔루션이다.
SELECT Orders.OrderNumber, LineItems.Quantity, LineItems.Description FROM Orders INNER JOIN ( SELECT Orders.OrderNumber, Max(LineItem.LineItemID) AS LineItemID FROM Orders INNER JOIN LineItems ON Orders.OrderNumber = LineItems.OrderNumber GROUP BY Orders.OrderNumber ) AS Items ON Orders.OrderNumber = Items.OrderNumber INNER JOIN LineItems ON Items.LineItemID = LineItems.LineItemID
-
==============================
3.당신은 할 수 있습니다 :
당신은 할 수 있습니다 :
SELECT Orders.OrderNumber, LineItems.Quantity, LineItems.Description FROM Orders INNER JOIN LineItems ON Orders.OrderID = LineItems.OrderID WHERE LineItems.LineItemID = ( SELECT MIN(LineItemID) FROM LineItems WHERE OrderID = Orders.OrderID )
이 인덱스 (또는 기본 키) LineItems.LineItemID에와 LineItems.OrderID에 인덱스를 필요로하거나 속도가 느려질 수 있습니다.
-
==============================
4.@Quassnoi 대답은 경우 (외부 테이블이 큰 특히 경우),보다 효율적인 쿼리가 다음과 같이 윈도우 잉 기능을 사용하여 수도에 좋다 :
@Quassnoi 대답은 경우 (외부 테이블이 큰 특히 경우),보다 효율적인 쿼리가 다음과 같이 윈도우 잉 기능을 사용하여 수도에 좋다 :
SELECT Orders.OrderNumber, LineItems2.Quantity, LineItems2.Description FROM Orders LEFT JOIN ( SELECT LineItems.Quantity, LineItems.Description, OrderId, ROW_NUMBER() OVER (PARTITION BY OrderId ORDER BY (SELECT NULL)) AS RowNum FROM LineItems ) LineItems2 ON LineItems2.OrderId = Orders.OrderID And RowNum = 1
가끔은 그냥 쿼리가 더 나은 성능을 제공합니다 테스트해야합니다.
-
==============================
5.공통 테이블 식을 사용하는 또 다른 방법을 :
공통 테이블 식을 사용하는 또 다른 방법을 :
with firstOnly as ( select Orders.OrderNumber, LineItems.Quantity, LineItems.Description, ROW_NUMBER() over (partiton by Orders.OrderID order by Orders.OrderID) lp FROM Orders join LineItems on Orders.OrderID = LineItems.OrderID ) select * from firstOnly where lp = 1
또는, 결국 어쩌면 당신은 가입 모든 행을 표시 하 고 싶습니다?
쉼표는 여기 버전을 분리 :
select * from Orders o cross apply ( select CAST((select l.Description + ',' from LineItems l where l.OrderID = s.OrderID for xml path('')) as nvarchar(max)) l ) lines
-
==============================
6.SQL 서버 2012 및 이후 나는이 트릭을 할 것입니다 생각 :
SQL 서버 2012 및 이후 나는이 트릭을 할 것입니다 생각 :
SELECT DISTINCT o.OrderNumber , FIRST_VALUE(li.Quantity) OVER ( PARTITION BY o.OrderNumber ORDER BY li.Description ) AS Quantity , FIRST_VALUE(li.Description) OVER ( PARTITION BY o.OrderNumber ORDER BY li.Description ) AS Description FROM Orders AS o INNER JOIN LineItems AS li ON o.OrderID = li.OrderID
-
==============================
7.상관 관계 서브 쿼리는 외부 쿼리에 따라 서브 쿼리이다. 그것은 SQL 루프에 대한 같아요. 하위 쿼리는 외부 쿼리의 각 행에 대해 한 번 실행됩니다 :
상관 관계 서브 쿼리는 외부 쿼리에 따라 서브 쿼리이다. 그것은 SQL 루프에 대한 같아요. 하위 쿼리는 외부 쿼리의 각 행에 대해 한 번 실행됩니다 :
select * from users join widgets on widgets.id = ( select id from widgets where widgets.user_id = users.id order by created_at desc limit 1 )
-
==============================
8.편집 : 신경 끄시 고, Quassnoi 더 나은 답을 가지고있다.
편집 : 신경 끄시 고, Quassnoi 더 나은 답을 가지고있다.
SQL2K,이 같은 경우 :
SELECT Orders.OrderNumber , LineItems.Quantity , LineItems.Description FROM ( SELECT Orders.OrderID , Orders.OrderNumber , FirstLineItemID = ( SELECT TOP 1 LineItemID FROM LineItems WHERE LineItems.OrderID = Orders.OrderID ORDER BY LineItemID -- or whatever else ) FROM Orders ) Orders JOIN LineItems ON LineItems.OrderID = Orders.OrderID AND LineItems.LineItemID = Orders.FirstLineItemID
-
==============================
9.하지 않은 절을 존재와이 쿼리를 실행하는 나의 마음에 드는 방법입니다. 나는이 쿼리의 종류를 실행하는 가장 효율적인 방법이라고 생각 :
하지 않은 절을 존재와이 쿼리를 실행하는 나의 마음에 드는 방법입니다. 나는이 쿼리의 종류를 실행하는 가장 효율적인 방법이라고 생각 :
select o.OrderNumber, li.Quantity, li.Description from Orders as o inner join LineItems as li on li.OrderID = o.OrderID where not exists ( select 1 from LineItems as li_later where li_later.OrderID = o.OrderID and li_later.LineItemGUID > li.LineItemGUID )
하지만 여기에 제안 다른 방법에 대해이 방법을 테스트하지 않았습니다.
-
==============================
10.십자가 시도, 잘 작동하지만 약간 더 오래 걸립니다. 조정 선 열이 속도를 유지하고 여분의 기록을 떨어 최대 및 추가 그룹이 있습니다.
십자가 시도, 잘 작동하지만 약간 더 오래 걸립니다. 조정 선 열이 속도를 유지하고 여분의 기록을 떨어 최대 및 추가 그룹이 있습니다.
여기 조정 된 쿼리는 다음과 같습니다
SELECT Orders.OrderNumber, max(LineItems.Quantity), max(LineItems.Description) FROM Orders INNER JOIN LineItems ON Orders.OrderID = LineItems.OrderID Group by Orders.OrderNumber
-
==============================
11.이 시도
이 시도
SELECT Orders.OrderNumber, LineItems.Quantity, LineItems.Description FROM Orders INNER JOIN ( SELECT Orders.OrderNumber, Max(LineItem.LineItemID) AS LineItemID FROM Orders INNER JOIN LineItems ON Orders.OrderNumber = LineItems.OrderNumber GROUP BY Orders.OrderNumber ) AS Items ON Orders.OrderNumber = Items.OrderNumber INNER JOIN LineItems ON Items.LineItemID = LineItems.LineItemID
from https://stackoverflow.com/questions/2043259/sql-server-how-to-join-to-first-row by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] .NET에서 Math.Max 같은 두 값을 사용합니다 SQL Server의 최대 기능이 있습니까? (0) | 2020.03.20 |
---|---|
[SQL] 무엇 TRUNCATE의 차이점은 그리고 SQL에서 DELETE (0) | 2020.03.20 |
[SQL] DoCmd.SetWarnings와 CurrentDB.Execute의 차이점은 무엇입니까 (0) | 2020.03.20 |
[SQL] 어떻게 MySQL의에서 행 생성기를해야합니까? (0) | 2020.03.20 |
[SQL] T-SQL 동적 피벗 (0) | 2020.03.20 |