如果符合特定条件,如何选择或跳到下一行

时间:2015-02-19 00:13:09

标签: sql sql-server tsql ranking

我真的不确定这个方向... 我正在尝试根据以下规则选择客户列表:

  • 从Customer中选择排名= 1,

  • 的所有行
  • OR如果Ranking = 1 AND Type = Store则排名1并返回排名为2的行。

  • 如果客户只有1行,即使type = Store也返回。

排名未在查询中分配Rank语句。而是它是Customer表中的实际列(由执行排名的存储过程填充)。

使用下面的示例,我希望返回第1,4,6和10行。

客户表

RowID   CustID  Type    Ranking

-----   ------  ----    -------

1       9       Web      1
2       9       Catalog  2
3       9       Store    3
4       10      Store    1
5       11      Store    1
6       11      Web      2
7       12      Store    1
8       12      Web      2
9       12      Catalog  3
10      13      Web      1

我觉得这个任务比较困难,因为在创建表时已经完成了排名!欢迎任何建议!

3 个答案:

答案 0 :(得分:1)

你可以尝试这样的东西(我还没有测试过它!):

SELECT
   RowId,
   CustId,
   Type,
   Ranking
FROM Customer c
WHERE (c.Ranking = 1 AND c.Type != 'Store')
   OR (c.Type = 'Store' AND Ranking = 2)
   OR (c.Type = 'Store' AND Ranking = 1 AND NOT EXISTS (SELECT 1 FROM Customer WHERE CustId = c.CustId AND Ranking = 2)) 

如果客户表很大,您可能会发现查询有点慢,这样的事情会更快:

SELECT
   RowId,
   CustId,
   Type,
   Ranking
FROM Customer c
WHERE c.Ranking = 1 AND c.Type != 'Store'

UNION ALL

SELECT
   RowId,
   CustId,
   Type,
   Ranking
FROM Customer c
WHERE c.Type = 'Store' AND Ranking = 2

UNION ALL

SELECT
   RowId,
   CustId,
   Type,
   Ranking
FROM Customer c
WHERE c.Type = 'Store' AND Ranking = 1 AND NOT EXISTS (SELECT 1 FROM Customer WHERE CustId = c.CustId AND Ranking = 2)

答案 1 :(得分:0)

与其他答案一样,我没有做过很多彻底的测试,但这就是我要看的内容。这里的想法是在数据集上优先化类型构建一个row_number:store to the top,然后使用rank作为二级排序条件。

select *
from (
select
    rid = row_number() over  (partition by CustID, order by case when type = 'Store' then 0 else 1 end, Rank desc),
    rowid,
    CustID,
    Type,
    Ranking
from customer)
where RID = 1

答案 2 :(得分:0)

尝试:

SELECT *
FROM Customer c
WHERE
-- There's only one row for this customer
(
    SELECT COUNT(*)
    FROM Customer
    WHERE CustID = c.CustID
) = 1
-- There's a row with Ranking = 1 and Type = 'Store', so select Ranking = 2
OR (Ranking = 2 AND EXISTS (SELECT 1 FROM Customer WHERE CustID = c.CustID AND Ranking = 1 AND Type = 'Store'))
-- There's a row with Ranking = 1 that's not Type = 'Store'
OR (Ranking = 1 AND Type <> 'Store')