1

想知道那里是否有人可能知道一个小 sql 脚本的技巧。

http://sqlfiddle.com/#!3/09638/3

我希望只返回具有手动变速器并且是福特制造的行。如果不存在行,则返回所有福特制造的车辆。我目前使用 IF EXISTs 条件来执行此操作。我考虑使用临时表来存储第一组数据,然后查看表的 rowcount()(插入的行数 == 0),看看是否需要插入更多数据。除了我描述的两个选项之外,可能没有其他方法可以做到这一点。也许社区对此有一些想法。

示例 DDL

CREATE TABLE Cars
(
  Make varchar(50),
  Model varchar(50),
  ManualTransmission bit
);


INSERT INTO Cars
(Make, Model, ManualTransmission)
VALUES
('Ford', 'Taurus', 0),
('Ford', 'Contour', 0),
('Ford', 'Mustang', 0),
('Jeep', 'Liberty', 1),
('Jeep', 'Cherokee', 0);
4

4 回答 4

6

单程

WITH CTE
     AS (SELECT *,
                RANK() OVER (ORDER BY ManualTransmission DESC) AS Rnk
         FROM   Cars
         WHERE  Make = 'Ford')
SELECT Make,
       Model,
       ManualTransmission
FROM   CTE
WHERE  Rnk = 1 

或其他

SELECT TOP 1 WITH TIES Make,
                       Model,
                       ManualTransmission
FROM   Cars
WHERE  Make = 'Ford'
ORDER  BY ManualTransmission DESC 

ManualTransmission这两个答案都利用了BIT数据类型这一事实,并且1是它可以拥有的最大可能值。如果ManualTransmission可以为空,那么您需要将它们更改为

ORDER BY ISNULL(ManualTransmission,0) DESC

或者

ORDER BY CASE WHEN ManualTransmission = 1 THEN 0 ELSE 1 END

CASE版本还将适用于更复杂的条件。

于 2013-01-07T20:26:26.670 回答
2

试试这个:

select *
from (select *,
             max(cast(ManualTransmission as int)) over (partition by make) as hasManual
      from cars
      where make = 'Ford'
     ) t
where hasManual = 0 or ManualTransmission = 1
于 2013-01-07T20:30:26.217 回答
1

我想我找到了一个相当便宜的方法?它似乎更便宜,因为它不需要做任何排序

;WITH CTE AS
(
    SELECT   *
            ,HasManual = SUM(CAST(ManualTransmission AS INT)) OVER (PARTITION BY Make)
    FROM Cars
)
SELECT Make, Model, ManualTransmission
FROM CTE 
WHERE   (Make = 'Ford' AND ManualTransmission = 1)
OR      (Make = 'Ford' AND HasManual = 0)
于 2013-01-07T20:58:43.410 回答
0

您可以尝试以下方法:

SELECT * FROM Cars
 WHERE Make = COALESCE('Ford', Make)
   AND ManualTransmission = COALESCE(1,ManualTransmission)
于 2013-01-07T20:26:56.560 回答