我有一个叫ClientUrls
表具有以下结构:存储过程通过优先返回基于空列数据
+------------+----------------+----------+
| ColumnName | DataType | Nullable |
+------------+----------------+----------+
| ClientId | INT | No |
| CountryId | INT | Yes |
| RegionId | INT | Yes |
| LanguageId | INT | Yes |
| URL | NVARCHAR(2048) | NO |
+------------+----------------+----------+
我有采用下列参数的存储过程up_GetClientUrls
:
@ClientId INT
@CountryId INT
@RegionId INT
@LanguageId INT
有关PROC信息
- 所有参数都是proc所需要的,它们都不会为NULL
- proc的目标是根据预定义的优先级在表中返回单个匹配行。优先级为ClientId> Country> Region>语言
- ClientUrls表中的三个colums可以为空。如果一列包含NULL,则表示“全部”。例如如果LanguageId为NULL,则它引用“AllLanguages”。所以如果我们发送一个5的LanguageId给proc,我们首先查找它,否则我们试着找到一个NULL。
矩阵优先的(1为第一)
+---------+----------+-----------+----------+------------+
| Ranking | ClientId | CountryId | RegionId | LanguageId |
+---------+----------+-----------+----------+------------+
| 1 | NOT NULL | NOT NULL | NOT NULL | NOT NULL |
| 2 | NOT NULL | NULL | NOT NULL | NOT NULL |
| 3 | NOT NULL | NOT NULL | NULL | NOT NULL |
| 4 | NOT NULL | NULL | NULL | NOT NULL |
| 5 | NOT NULL | NOT NULL | NOT NULL | NULL |
| 6 | NOT NULL | NULL | NOT NULL | NULL |
| 7 | NOT NULL | NULL | NULL | NULL |
+---------+----------+-----------+----------+------------+
下面是一些例子数据:
+----------+-----------+----------+------------+-------------------------------+
| ClientId | CountryId | RegionId | LanguageId | URL |
+----------+-----------+----------+------------+-------------------------------+
| 1 | 1 | 1 | 1 | http://www.Website.com |
| 1 | 1 | 1 | NULL | http://www.Otherwebsite.com |
| 1 | 1 | NULL | 2 | http://www.Anotherwebsite.com |
+----------+-----------+----------+------------+-------------------------------+
实施例存储的过程呼叫
EXEC up_GetClientUrls @ClientId = 1
,@CountryId = 1
,@RegionId = 1
,@LanguageId = 2
预期响应(基于示例的数据)
+----------+-----------+----------+------------+-------------------------------+
| ClientId | CountryId | RegionId | LanguageId | URL |
+----------+-----------+----------+------------+-------------------------------+
| 1 | 1 | NULL | 2 | http://www.Anotherwebsite.com |
+----------+-----------+----------+------------+-------------------------------+
返回该行因为上一个NULL RegionId匹配与正确LanguageId比上具有正确RegionId一个NULL LanguageId匹配更高的优先级。
这里是proc(它工作)的代码。为了真正解决我的问题,有没有更好的方法来写这个?如果我在将来扩展这个表,我将继续乘以UNION语句的数量,因此它不是真正可扩展的。
实际的存储过程
CREATE PROC up_GetClientUrls
(
@ClientId INT
,@CountryId INT
,@RegionId INT
,@LanguageId INT
)
AS
BEGIN
SELECT TOP 1
prioritised.ClientId
,prioritised.CountryId
,prioritised.RegionId
,prioritised.LanguageId
,prioritised.URL
FROM
(
SELECT
c.ClientId
,c.CountryId
,c.RegionId
,c.LanguageId
,c.URL
,1 [priority]
FROM ClientUrls c
WHERE c.ClientId = @ClientId
AND c.CountryId = @CountryId
AND c.RegionId = @RegionId
AND c.LanguageId = @LanguageId
UNION
SELECT
c.ClientId
,c.CountryId
,c.RegionId
,c.LanguageId
,c.URL
,2 [priority]
FROM ClientUrls c
WHERE c.ClientId = @ClientId
AND c.CountryId IS NULL
AND c.RegionId = @RegionId
AND c.LanguageId = @LanguageId
UNION
SELECT
c.ClientId
,c.CountryId
,c.RegionId
,c.LanguageId
,c.URL
,3 [priority]
FROM ClientUrls c
WHERE c.ClientId = @ClientId
AND c.CountryId = @CountryId
AND c.RegionId IS NULL
AND c.LanguageId = @LanguageId
UNION
SELECT
c.ClientId
,c.CountryId
,c.RegionId
,c.LanguageId
,c.URL
,4 [priority]
FROM ClientUrls c
WHERE c.ClientId = @ClientId
AND c.CountryId IS NULL
AND c.RegionId IS NULL
AND c.LanguageId = @LanguageId
UNION
SELECT
c.ClientId
,c.CountryId
,c.RegionId
,c.LanguageId
,c.URL
,5 [priority]
FROM ClientUrls c
WHERE c.ClientId = @ClientId
AND c.CountryId = @CountryId
AND c.RegionId = @RegionId
AND c.LanguageId IS NULL
UNION
SELECT
c.ClientId
,c.CountryId
,c.RegionId
,c.LanguageId
,c.URL
,6 [priority]
FROM ClientUrls c
WHERE c.ClientId = @ClientId
AND c.CountryId IS NULL
AND c.RegionId = @RegionId
AND c.LanguageId IS NULL
UNION
SELECT
c.ClientId
,c.CountryId
,c.RegionId
,c.LanguageId
,c.URL
,7 [priority]
FROM ClientUrls c
WHERE c.ClientId = @ClientId
AND c.CountryId IS NULL
AND c.RegionId IS NULL
AND c.LanguageId IS NULL
) prioritised
ORDER BY prioritised.[Priority]
END
您的客户端ID是否在表中是唯一的?我的意思是如果我可以得到'[Client_id 1 Country 1],[client_id 1,country 2]' – lad2025
ClientId,CountryId,RegionId和LanguageId应该都是唯一的(包括NULLS唯一)。 – JBond
您使用'TOP 1'我应该检查当前代码中的'TOP 1 WITH TIES',因为不知道您的索引是不是很明显。 – lad2025