我有一个包含4个char错误代码的表及其描述。 我在一个字符串中有一个销售表,其中包含多个错误代码。 我设计了一个使用类似的连接,允许加入最高加权的错误代码,除非2个或更多错误具有相同的权重,这会创建多个连接的行,这样就可以正常工作。
如果权重相等,我只想要1个结果(任何会做)
TABLE ErrorCodes
Code | Description | Weight
'0041' | 'data error' | 4
'0019' | 'format error' | 2
'0099' | 'missing creator' | 2
TABLE MyData
ID | RespCode
1234 | '00410019'
1235 | '00990019'
结果我
ID | RespCode | Description
1234 | '00410019' | 'data error'
1235 | '00990019' | 'format error'
1235 | '00990019' | 'missing creator'
我只想要1235的1个结果,但即使在子选择中使用Max或Top 1,我也得到2个。我怎样才能限制为1个连接的行?
SELECT * FROM MyData
left JOIN ErrorCodes
ON MyData.RespCode
LIKE '%' + ErrorCodes.Code + '%'
AND ErrorCodes.Weight = (
SELECT MAX (Weight) FROM ErrorCodes
WHERE MyDate.RespCode LIKE '%' + ErrorCodes.Code + '%'
)
答案 0 :(得分:1)
Window Functions to the rescue! :-)
SELECT ec2.ID, ec2.RespCode, ec2.[Description]
FROM (
SELECT ec1.ID, ec1.RespCode, ec1.Code, ec1.[Description], ec1.[Weight] , ROW_NUMBER() OVER ( PARTITION BY ec1.ID ORDER BY ec1.[Weight] ASC ) AS rn
FROM (
SELECT
md.id
, md.RespCode
, ec.Code
, ec.[Description]
, ec.[Weight]
FROM #myData md
LEFT OUTER JOIN #ErrorCodes ec ON md.RespCode LIKE '%' + ec.Code + '%'
) ec1
) ec2
WHERE ec2.rn = 1
答案 1 :(得分:1)
SELECT
ID, RespCode, Description
FROM
(
SELECT
ID,
RespCode,
Description,
ROW_NUMBER() OVER(PARTITION BY ID ORDER BY Weight DESC) as rown
FROM
MyData
LEFT JOIN
ErrorCodes
ON
MyData.RespCode LIKE '%' + ErrorCodes.Code + '%'
) a
WHERE
rown = 1
Need a recent version of SQLS (2008+) for this. You take your query with all the duplicated row ids, and you ask SQLserver to do an in-place aggregating (partition by) and row numbering; it will give a counter that counts 1, 2, 3, etc for each ID, the counter restarts upon a change of ID (thanks to partition by), and the rows it counts are ordered by weight descending (higher weight comes first
Then we just select only rows where the counter is 1
To see what I mean about the inner query, just highlight that one between the brackets and run it, to see the ROWN column and how it behaves
Note: I see that Shawn's query is more or less same (Sorry Shawn, only looked closely at your query after I wrote mine, because the windowing function was off screen due to long lines), only has an extra unneeded subquery, and also his partiton/order by clause is wrong (it selects the lowest weighted weight thanks to ASC, you wanted highest weight to take precedence)
答案 2 :(得分:0)
使用以下查询
SELECT * FROM MyData
left JOIN ErrorCodes
ON MyData.RespCode
LIKE '' + ErrorCodes.Code + '%'
AND ErrorCodes.Weight = (
SELECT MAX (Weight) FROM ErrorCodes
WHERE MyDate.RespCode LIKE '%' + ErrorCodes.Code + '%'
)