SQL SERVER 2008 R2。两个表具有1-many关系,并且希望两者都有一些字段,但在很多方面,只需要来自某一行的值。该行由某些条件指定,在我的情况下,该行应该具有该PaymentId的最小ClaimId。
IF OBJECT_ID('tempdb..#Payments') IS NOT NULL DROP TABLE #Payments
CREATE TABLE #Payments ( PaymentId int UNIQUE NOT NULL )
INSERT INTO #Payments ( PaymentId )
VALUES (1), (2), (3)
IF OBJECT_ID('tempdb..#Claims') IS NOT NULL DROP TABLE #Claims
CREATE TABLE #Claims ( PaymentId int NOT NULL, ClaimId int NOT NULL, FirstName varchar(50) NOT NULL )
INSERT INTO #Claims ( PaymentId, ClaimId, FirstName )
VALUES (1, 51,'Joe'), (1, 57,'Jane'), (2, 62,'Spot'), (2, 63,'Rover'), (3, 88,'Sue'), (3, 89,'Sally')
SELECT * FROM #Payments p
JOIN #Claims c ON p.PaymentId=c.PaymentId
WHERE c.ClaimId=MIN(ClaimId)
GROUP BY p.PaymentId
HAVING MIN(ClaimId)
期望的结果如下,其中声明来自具有给定paymentId的最小claimId的行。 ClaimId可能不会被订购,因此寻求最低限度,而不是首先。
PaymentId ClaimId FirstName
1 51 Joe
2 62 Spot
3 88 Sue
我很乐意提及现有的问题/答案,但我不知道怎么说这个,我发现类似的东西。也许是Get field value from a record that causes an aggregate condition to be true,但我对此并不了解。
答案 0 :(得分:2)
您可以使用ROW_NUMBER
窗口功能,如下所示:
SELECT PaymentId, ClaimId, FirstName
FROM
(
SELECT
p.PaymentId,
c.ClaimId,
c.FirstName,
ROW_NUMBER() OVER (PARTITION BY p.PaymentId ORDER BY c.ClaimId) as RN
FROM #Payments p
JOIN #Claims c ON p.PaymentId=c.PaymentId
) as T
WHERE RN = 1
答案 1 :(得分:1)
在SQL Server中,我喜欢使用outer apply
:
select p.*, c.*
from #Payments p outer apply
(select top 1 c.*
from #Claims c
where c.paymentid = p.paymentid
order by c.claimid
) c;
答案 2 :(得分:1)
使用foreach(DataRow row in ((DataTable)this.grdPart.DataSource).Select("Seleccionar= true"))
{
string sub = row["SUB"].ToString();
string p1 = row["P1"].ToString();
string p2 = row["P2"].ToString();
string p3 = row["P3"].ToString();
}
RANK()
答案 3 :(得分:1)
使用windows function row_number提供订单
;with cte as
(
select PaymentID, ClaimID, row_number() over (partition by PaymentID order by ClaimID ) as rn
from #Claims
)
select p.*,cte.ClaimID
from #Payments p
join cte on cte.paymentID = p.paymentID
where rn=1 --limits to earliest claimid
答案 4 :(得分:1)
两个句子都返回相同的结果,首先为每个PaymentId选择MIN(ClaimId):
SELECT P.*, C.*
FROM #Payments P
INNER JOIN #Claims C ON C.PaymentId = P.PaymentId
WHERE C.ClaimID IN (SELECT MIN(ClaimID) OVER (PARTITION BY PaymentId) FROM #Claims);
第二次使用CTE在加入Payments表之前找到MIN(ClaimId):cº
WITH PY AS
(
SELECT PaymentId, MIN(ClaimId) as ClaimID
FROM #Claims
GROUP BY PaymentId
)
SELECT PY.PayMentId, PY.ClaimId, C.FirstName, P.*
FROM PY
LEFT JOIN #Claims c ON p.ClaimId = c.ClaimId;
LEFT JOIN #Payments P ON P.PaymentId = PY.PaymentId
+-----------+---------+-----------+
| PayMentId | ClaimId | FirstName |
+-----------+---------+-----------+
| 1 | 51 | Joe |
+-----------+---------+-----------+
| 2 | 62 | Spot |
+-----------+---------+-----------+
| 3 | 88 | Sue |
+-----------+---------+-----------+