SQL - 返回特殊行,然后根据搜索条件返回通用

时间:2015-02-10 15:18:02

标签: sql

我有一个包含样式代码和型号代码的表格以及定价信息。

MODEL CODE - STYLE CODE - PRICE
10000      - STD        - 150.00
10500      - FEL        - 25.50
10500      - STD        - 19.90
20050      - GEK        - 130.00
20050      - FEL        - 99.99
20050      - STD        - 50.00
40330      - GEK        - 39.00
40330      - STD        - 19.00

您可以确定每个型号代码都有可用的STD样式代码。 我想要一个查询,可以找到特定样式的所有模型代码的总价格,但如果特定型号不存在该样式,则需要标准价格。

例如,如果我想从这张表中得到FEL价格,我会得到293.49 (10000-STD @ 150 + 10500-FEL @ 25.50 + 20050-FEL @ 99.99 + 40330-STD @ 19.00)

3 个答案:

答案 0 :(得分:1)

-- first select the model codes.
WITH models AS
(
  SELECT DISTINCT MODEL_CODE
  FROM TABLENAME
), val_list AS
(
  -- then left join back to the table and pick the style or default.
  SELECT m.MODEL_CODE, COALESCE(x.PRICE,d.PRICE) AS PRICE
  FROM models m
  LEFT JOIN TABLENAME d ON d.MODEL_CODE = m.MODEL_CODE AND d.STYLE_CODE = 'STD'
  LEFT JOIN TABLENAME x ON x.MODEL_CODE = m.MODEL_CODE AND x.STYLE_CODE = 'FEL'
),
SELECT SUM(PRICE)
FROM val_list

请注意,如果您不能使用CTE,以下内容将执行相同的操作:

SELECT SUM(PRICE)
FROM (
  SELECT m.MODEL_CODE, COALESCE(x.PRICE,d.PRICE) AS PRICE
  FROM (SELECT DISTINCT MODEL_CODE FROM TABLENAME) m
  LEFT JOIN TABLENAME d ON d.MODEL_CODE = m.MODEL_CODE AND d.STYLE_CODE = 'STD'
  LEFT JOIN TABLENAME x ON x.MODEL_CODE = m.MODEL_CODE AND x.STYLE_CODE = 'FEL'
) val_list

要了解其工作原理,您可以查看不同的部分 - 尝试

-- first select the model codes.
WITH models AS
(
  SELECT DISTINCT MODEL_CODE
  FROM TABLENAME
)
SELECT m.MODEL_CODE, x.PRICE, d.PRICE
FROM models m
LEFT JOIN TABLENAME d ON d.MODEL_CODE = m.MODEL_CODE AND d.STYLE_CODE = 'STD'
LEFT JOIN TABLENAME x ON x.MODEL_CODE = m.MODEL_CODE AND x.STYLE_CODE = 'FEL'

-- first select the model codes.
WITH models AS
(
  SELECT DISTINCT MODEL_CODE
  FROM TABLENAME
), val_list AS
(
  -- then left join back to the table and pick the style or default.
  SELECT m.MODEL_CODE, COALESCE(x.PRICE,d.PRICE) AS PRICE
  FROM models m
  LEFT JOIN TABLENAME d ON d.MODEL_CODE = m.MODEL_CODE AND d.STYLE_CODE = 'STD'
  LEFT JOIN TABLENAME x ON x.MODEL_CODE = m.MODEL_CODE AND x.STYLE_CODE = 'FEL'
)
SELECT *
FROM val_list

答案 1 :(得分:0)

这是另一种方法

  with w_styles as (
        select model_cd,
               style_cd,
               price,
               row_number() over (partition by model_cd order by case when style_cd = 'STD' then 'ZZZ' else style_cd end ) r
          from <yourtable>
         where style_cd in ( 'FEL', 'STD' )
     )
  select model_cd, style_cd, price
    from w_styles
   where r = 1

这只是收集&#34; FEL&#34;或默认的&#34; STD&#34;记录,然后按照模型cd对它们进行分组,优先选择FEL代码,而不是STD(如果有的话)。 然后丢弃它不需要的东西

答案 2 :(得分:0)

这是一种方法。

declare @style as varchar(3)
set @style = 'Fel'

SELECT sum(price) as [Price]
FROM
(
SELECT 
t1.[model code], 
t1.[style code], 
t1.price
FROM myTable t1
WHERE ([style code] = @style)

UNION

SELECT 
t1.[model code], 
t1.[style code], 
t1.price
FROM myTable t1
WHERE ([style code] = 'Std')
AND NOT EXISTS 
(SELECT null FROM myTable t2 WHERE t2.[model code]= t1.[model code] and t2.[style code] =  @style)
) A

要逐步执行此操作,此部分会获取样式与您所选样式匹配的每一行:

SELECT 
t1.[model code], 
t1.[style code], 
t1.price
FROM myTable t1
WHERE ([style code] = @style)

然后我们将其余模型与工会结合到那些结果中。我们只想添加模型编号没有查询样式代码的行。我使用了self join和exists语句来完成它。

SELECT 
t1.[model code], 
t1.[style code], 
t1.price
FROM myTable t1
WHERE ([style code] = 'Std') -- standard codes 
AND NOT EXISTS               -- where there is not style of 'Fel'
(SELECT null FROM myTable t2 WHERE t2.[model code]= t1.[model code] and t2. [style code] =  @style)

此时您已经获得了所需的所有型号,款式和价格的表格,因此您只需对价格求和。