如何为表中的每个公司只获得一个结果?

时间:2013-03-01 19:33:30

标签: sql sql-server-2008

我有查询但现在我需要将查询更改为数据库,以便只为表Price中的每个公司获得一个结果。

为此我添加行GROUP by p.id_firm,然后我得到下一个查询:

SELECT TOP 20 
  p.id_price as p_id_price, 
  p.id_service as p_id_service, 
  p.name as p_name, 
  p.name_original as p_name_original, 
  p.id_producer_country as p_id_producer_country, 
  p.id_firm as p_id_firm, 
  f.name as f_name, 
  f.address as f_address, 
  f.phone as f_phone, 
  city.name as city_name, 
  pc.name as pc_name 
FROM Price p 
left join Firm f 
  on f.id_service=p.id_service 
  AND f.id_city=p.id_city 
  AND f.id_firm=p.id_firm 
left join City city 
  on city.id_city = p.id_city 
left join Producer_country pc 
  on pc.id_producer_country = p.id_producer_country 
WHERE p.id_city='73041' 
  AND p.include='1' 
  AND p.blocked='0' 
  AND f.blocked='0' 
  AND ( f.name LIKE 'Окно%' COLLATE SQL_Latin1_General_Cp1251_CI_AS OR p.name LIKE 'Окно%' COLLATE SQL_Latin1_General_Cp1251_CI_AS ) 
GROUP by p.id_firm ORDER BY p.name ASC

但如果我使用它,我会收到错误:

  

Msg 8120,Level 16,State 1,Line 2   “Price.id_price”列在选择列表中无效,因为它不包含在聚合函数或GROUP BY子句中。

请以正确的方式告诉我更改此查询或者制作其他查询?

构建您可以看到的所有表格here

P.S。:抱歉不准确。按公司名称和产品名称搜索。如果搜索词包含在产品名称或公司名称中,并且某些结果具有相同的id_firm,则需要选择一个最合适的值,即结果中的id_firm搜索应该是唯一的。

2 个答案:

答案 0 :(得分:1)

使用ROW_NUMBER()代替分组。

分别为每个公司的行编号。对ROW_NUMBER()的行进行排序时,请使用p.name LIKE 'Окно%'条件将匹配产品的行放在其他行之前。

以下是一个示例:

;
WITH ranked AS (
  SELECT
    p.id_price as p_id_price, 
    p.id_service as p_id_service, 
    p.name as p_name, 
    p.name_original as p_name_original, 
    p.id_producer_country as p_id_producer_country, 
    p.id_firm as p_id_firm, 
    f.name as f_name, 
    f.address as f_address, 
    f.phone as f_phone, 
    city.name as city_name, 
    pc.name as pc_name,
    ROW_NUMBER() OVER (
      PARTITION BY p.id_firm
      ORDER BY
        CASE  -- this criterion puts matching products before non-matching ones
          WHEN p.name LIKE 'Окно%' COLLATE SQL_Latin1_General_Cp1251_CI_AS
          THEN 1 ELSE 2
        END,
        p.id_price  -- you may use any sorting criteria at this point,
                    -- just ensure it makes the results predictable
    ) AS rnk
  FROM Price p 
  left join Firm f 
    on f.id_service=p.id_service 
    AND f.id_city=p.id_city 
    AND f.id_firm=p.id_firm 
  left join City city 
    on city.id_city = p.id_city 
  left join Producer_country pc 
    on pc.id_producer_country = p.id_producer_country 
  WHERE p.id_city='73041' 
    AND p.include='1' 
    AND p.blocked='0' 
    AND f.blocked='0' 
    AND ( f.name LIKE 'Окно%' COLLATE SQL_Latin1_General_Cp1251_CI_AS
       OR p.name LIKE 'Окно%' COLLATE SQL_Latin1_General_Cp1251_CI_AS ) 
)
SELECT TOP 20
  p_id_price, 
  p_id_service, 
  p_name, 
  p_name_original, 
  p_id_producer_country, 
  p_id_firm, 
  f_name, 
  f_address, 
  f_phone, 
  city_name, 
  pc_name
FROM ranked
WHERE rnk = 1
-- the absence of ORDER BY makes your TOP 20 results indeterminate
;

基本上,这会对每个公司的行进行排名,然后只从所有公司中抽取排名为1的行,使每个公司最终排成一行。

答案 1 :(得分:0)

您可以尝试选择Distinct以获得可能的快速修复 http://www.w3schools.com/sql/sql_distinct.asp