2016-12-13 111 views
0

我有一张名为DefaultCountries的表格。动态SQL Case语句?

它包含以下几列:

  • CountryID INT
  • DefaultCountryID INT
  • CountryRank INT

我有29名不同的国家有每个国家不同的数据。例如:

1 CountryID具有2个记录:

CountryID1

7 CountryID具有3个记录

CountryID7

我有可变的表@CountryData,我试图到加入到目前具有国家ID 1和10的数据。

Example Table

我希望能够匹配到DefaultCountries表中找到的DefaultCountryID。其中,有超过2+排在那里我有一个问题是

SELECT TOP 1 DefaultCountryID 
WHERE CountryID = 1  -- that is my simple case. 

:所以,如果我通过在CountryID = 1,我可以做这样的事情。正如我在CountryID = 7的例子。基本上我想有一些东西,如果我的表中没有记录,我试图加入第一条记录(CountryRank = 1),那么我希望它能够搜索下一条记录。

因此,搜索CountryID = 7,那么如果没有,然后CountryID = 10(如此等等)。

我已经试过这让不同的变化JOIN

SELECT * 
FROM @CountryData cd 
LEFT JOIN DefaultCountries dc ON dc.defaultCountryid = cd.CountryID 
           AND cd.CountryID = 7 

但这只是带回的所有数据(1 & 10)。我是否必须按照我描述的方式使用循环来执行此操作?我也考虑过CASE声明,但由于我在DefaultCountries表中可能有超过2+,所以我不知道如何继续搜索。

我试着做一个IN语句,但我有2个问题。我不能在声明中,我得到以下信息做一个顺序:

ORDER BY子句在视图,内联函数无效,派生 表,子查询和公用表表达式,除非TOP ,还指定了OFFSET 或FOR XML。

即使有一种方法可以确保我按照我要使用IN语句的顺序搜索,但我想确保它在找到的第一个搜索条件中停止搜索。因此,扩展我的例子,如果table(@CountryData)表现在包含CountryID = 7和CountryID = 10的记录,我只想返回CountryID = 7的记录。

+0

为什么不加入它在rank = 1的地方呢?也许我在这里错过了一些东西。每个国家会不会有一个排名= 1的排名? – scsimon

+0

@scsimon - DefaultCountries表中总会有一个rank = 1。 – webdad3

+2

你可能会看看'ROW_NUMBER()OVER(ORDER BY ...)AS Nr'。通常这样的事情可以通过'CTE'来解决,在'OVER()'中定义的排序子句之后对行进行编号。最后一个'SELECT'在'WHERE Nr = 1'上使用过滤器# – Shnugo

回答

1

,如果我跟着你的权利,你可以只使用一个CTE

with cte as(
select 
    CountryID, 
    DefaulteCountryID, 
    ROW_NUMBER() over (partition by CountryID order by CountryRank) as rn 
from DefaultCountries 
where DefaultCountryID in (select distinct CountryID from @CountryData)) 

然后刚刚加入这个CTE where rn = 1

所以这将满足“基本上我想有一些地方,如果有在我的表中没有记录,我试图加入第一条记录(CountryRank = 1),那么我希望它搜索下一个记录“意思是如果没有1,你会得到2或3 ,或者下一个订单号码是什么。

+0

只有DefaultCountries有CountryRank,其他表(在我的示例CountryData中)只有一个countryid - 当我加入其中rn = 1时,我没有行。 – webdad3

+0

@ webdad3所以国家排名为空...或...?还有哪些桌子? – scsimon

+0

我更新了我的问题以确定没有CountryRank的表格 - 让我知道是否需要添加更多说明。我的例子中的这个表是一个临时表。但它代表了我无法截图的物理表格。 – webdad3