SQL服务器上 - 选择TOP 5行每个FK(SQL Server - SELECT TOP 5 r

2019-08-08 03:28发布

我有以下查询,看起来最多的前5名匹配的商品搜索。 每个产品与一个店铺相关

SELECT TOP 5 * FROM产品P,商店S其中p.ShopId = s.ShopId和p.ProductName LIKE '%圣诞%'

我需要扩展这一点,以便它返回我在每个 的TOP 5 的产品

任何人都可以让我知道了如何查询可以修改实现这一目标? -即选择在每个店(而非其显示,前5个产品匹配的“%圣诞%”在所有店的电流)的TOP 5的产品匹配的“圣诞%%”。

Answer 1:

你实际上缺少一个ORDER BY,使TOP有意义的,或基于ROW_NUMBER任何解决方案,它需要一个ORDER BY。

SELECT
    *
FROM
    Shops s 
CROSS APPLY (
    SELECT TOP 5
        *
    FROM
        Products p
    WHERE
        p.ShopId = s.ShopId AND p.ProductName LIKE '%christmas%'
    ORDER BY --added on edit
        ???
) X


Answer 2:

试试这个:

select * from (
    select *, rn = row_number() over (partition by s.ShopId order by p.ProductName)
    from Products p, Shops s 
    where p.ShopId = s.ShopId AND p.ProductName LIKE '%christmas%'
) a where a.rn <= 5


Answer 3:

试试这个

SELECT DISTINCT 
        A.Product_Group_code
        ,B.Sub_Product_Group_code
        ,A.Product_code
        ,A.Product_name
FROM dbo.A A
    LEFT JOIN dbo.B B
        ON A.Product_code = B.Product_code
WHERE  B.Product_code IN
                (
                    SELECT TOP 5 E.Product_code
                    FROM dbo.A D
                        LEFT JOIN dbo.B E
                            ON D.Product_code = E.Product_code
                    WHERE E.Sub_Product_Group_code = B.Sub_Product_Group_code
                )
        AND B.Sub_Product_Group_code IS NOT NULL
ORDER BY B.Sub_Product_Group_code,A.Product_name


Answer 4:

这里是一个很好的解决方案我刚刚发现。

选择TOP N行的每​​个组阿尼·罗兰,2008年3月13日,

有每个类别多行,而只以价格只能选择每个类别的前两名(2)行的愿望。 例如,从以下数据:

RowID    Category    ID  Description     Price
1    Pot     A1  Small Saucepan  21.50
2    Pot     A2  1 Qt Saucepan   29.95
3    Pot     A3  1.5 Qt Saucepan     33.95
4    Pot     A4  Double Boiler   39.50
5    Pot     A5  Stewpot     49.50
6    Pot     A6  Pressure Cooker     79.95
7    Pan     B1  8" Pie  6.95
8    Pan     B2  8" Sq Cake  7.50
9    Pan     B3  Bundt Cake  12.50
10   Pan     B4  9x12 Brownie    7.95
11   Bowl    C1  Lg Mixing   27.50
12   Bowl    C2  Sm Mixing   17.50
13   Tools   T1  14" Spatula     9.95

所期望的输出是:

RowID    Category    ID  Description     Price
11   Bowl    C1  Lg Mixing   27.50
12   Bowl    C2  Sm Mixing   17.50
9    Pan     B3  Bundt Cake  12.50
10   Pan     B4  9x12 Brownie    7.95
6    Pot     A6  Pressure Cooker     79.95
5    Pot     A5  Stewpot     49.50
13   Tools   T1  14" Spatula     9.95

有几种方法来完成所需的输出。 此演示提供了对SQL Server 2005 / SQL Server 2008中,然后用于SQL Server 2000一个解决方案的解决方案。

创建两种解决方案示例数据

-- Suppress data loading messages
SET NOCOUNT ON

-- Create Sample Data using a Table Varable
DECLARE @MyTable table
   (  RowID         int   IDENTITY, 
      Category      varchar(5),
      [ID]          varchar(5),
      [Description] varchar(25),
      Price         decimal(10,2)
   )

-- Load Sample Data

INSERT INTO @MyTable VALUES ( 'Pot', 'A1', 'Small Saucepan', 21.50 )
INSERT INTO @MyTable VALUES ( 'Pot', 'A2', '1 Qt Saucepan', 29.95 )
INSERT INTO @MyTable VALUES ( 'Pot', 'A3', '1.5 Qt Saucepan', 33.95 )
INSERT INTO @MyTable VALUES ( 'Pot', 'A4', 'Double Boiler', 39.50 )
INSERT INTO @MyTable VALUES ( 'Pot', 'A5', 'Stewpot', 49.50 )
INSERT INTO @MyTable VALUES ( 'Pot', 'A6', 'Pressure Cooker', 79.95 )
INSERT INTO @MyTable VALUES ( 'Pan', 'B1', '8"" Pie', 6.95 )
INSERT INTO @MyTable VALUES ( 'Pan', 'B2', '8"" Sq Cake', 7.50 )
INSERT INTO @MyTable VALUES ( 'Pan', 'B3', 'Bundt Cake', 12.50 )
INSERT INTO @MyTable VALUES ( 'Pan', 'B4', '9x12 Brownie', 7.95 )
INSERT INTO @MyTable VALUES ( 'Bowl', 'C1', 'Lg Mixing', 27.50 )
INSERT INTO @MyTable VALUES ( 'Bowl', 'C2', 'Sm Mixing', 17.50 )
INSERT INTO @MyTable VALUES ( 'Tools', 'T1', '14"" Spatula', 9.95 )
Return to Top

的SQL Server 2005 / SQL Server 2008中的解决方案

--Query to Retrieve Desired Data
SELECT
   RowID,
   Category,
   [ID],
   [Description],
   Price
FROM (SELECT
         ROW_NUMBER() OVER ( PARTITION BY Category ORDER BY Price DESC ) AS 'RowNumber',
         RowID,
         Category,
         [ID],
         [Description],
         Price
      FROM @MyTable
      ) dt
WHERE RowNumber <= 2

-- Results
RowID Category  ID Description     Price
11    Bowl      C1 Lg Mixing       27.50
12    Bowl      C2 Sm Mixing       17.50
9     Pan       B3 Bundt Cake      12.50
10    Pan       B4 9x12 Brownie    7.95
6     Pot       A6 Pressure Cooker 79.95
5     Pot       A5 Stewpot         49.50
13    Tools     T1 14" Spatula     9.95
Return to Top

的SQL Server 2005 / SQL服务器使用CTE 2008解决方案(添加人:雅各塞巴斯蒂安)

-- Define a CTE with the name "dt" 
;WITH dt AS (
     SELECT
         ROW_NUMBER() OVER ( PARTITION BY Category ORDER BY Price DESC ) AS 'RowNumber',
         RowID,
         Category,
         [ID],
         [Description],
         Price
      FROM @MyTable
)
-- and select the data from the CTE
SELECT
   RowID,
   Category,
   [ID],
   [Description],
   Price
FROM dt
WHERE RowNumber <= 2

-- Results
RowID Category  ID Description     Price
11    Bowl      C1 Lg Mixing       27.50
12    Bowl      C2 Sm Mixing       17.50
9     Pan       B3 Bundt Cake      12.50
10    Pan       B4 9x12 Brownie    7.95
6     Pot       A6 Pressure Cooker 79.95
5     Pot       A5 Stewpot         49.50
13    Tools     T1 14" Spatula     9.95
Return to Top

SQL 2000解决方案

--Query to Retrieve Desired Data
SELECT DISTINCT
   RowID,
   Category,
   [ID],
   [Description],
   Price
FROM @MyTable t1
WHERE RowID IN (SELECT TOP 2
                   RowID
                FROM @MyTable t2
                WHERE t2.Category = t1.Category
                ORDER BY Price DESC
               )
ORDER BY 
   Category,
   Price DESC

-- Results
RowID Category  ID Description     Price
11    Bowl      C1 Lg Mixing       27.50
12    Bowl      C2 Sm Mixing       17.50
9     Pan       B3 Bundt Cake      12.50
10    Pan       B4 9x12 Brownie    7.95
6     Pot       A6 Pressure Cooker 79.95
5     Pot       A5 Stewpot         49.50
13    Tools     T1 14" Spatula     9.95

来源: 选择TOP N行的每个组



文章来源: SQL Server - SELECT TOP 5 rows for each FK