通过连接多个表来获取计数以及一个顶行描述

时间:2016-12-13 13:09:51

标签: sql sql-server

我们需要在单个查询中显示子表行的数量以及前1个最后一行对象名称,下面是详细信息:


Table 1
CategoryID   Name 
1           Fruits 
2           Foods
3           Drinks

Table 2
ProductID   Name    CategoryID
1           Banana      1
2           Mango       1
3           Pineapple   1
4           Whisky      3
5           Water       3


Result
CategoryID      Name        Items       ItemDisplayText
1               Fruits      3           Pineapple & More 2

我已经搜索了许多其他问题,很可能会有一个相同的问题,但是我找不到那个问题,任何帮助都会得到满足。

由于

4 个答案:

答案 0 :(得分:1)

我创建了临时表:

declare @table1 table ( category int,
                    name varchar(10)
                    )

declare @table2 table ( product int,
                    name varchar(10),
                    category int
                    )

insert into @table1 (category, name)
values  (1, 'Fruits'),
        (2, 'Foods'),
        (3, 'Drinks')

insert into @table2 (product, name, category)
values  (1, 'Banana', 1),
        (2, 'Mango', 1),
        (3, 'Pineapple', 1),
        (4, 'Whisky', 3),
        (5, 'Water', 3)

然后,以下查询:

select t1.*, 
count(t2.product) as items, 
(select top 1 name from @table2 where category = t1.category order by product desc) + ' & more ' + convert(varchar(10), count(t2.product) - 1) as 'item display text'
from @table1 t1 join @table2 t2 on t1.category = t2.category
group by t1.category, t1.name

获得的结果:

category    name       items       item display text
----------- ---------- ----------- ----------------------------
1           Fruits     3           Pineapple & more 2
3           Drinks     2           Water & more 1

(2 row(s) affected)

希望它有所帮助。

编辑: 对于注释问题:您可以使用xml结果(如果需要,可以更改顶部约束和减法):

select t1.*, 
count(t2.product) as items, 
stuff((select ', ' + t.n from (select top 2 name as n from @table2 where category = t1.category order by product desc) t for xml path('')), 1, 1, '') + ' & more ' + convert(varchar(10), count(t2.product) - 2) as 'item display text'
from @table1 t1 join @table2 t2 on t1.category = t2.category
group by t1.category, t1.name

答案 1 :(得分:0)

诀窍似乎是显示文字。我会使用row_number()进行条件聚合以获取您想要的产品名称:

select t2.categoryId, t2.name, count(*) as Items,
       (max(case when seqnum = 1 then t2.name end) +
        (case when count(*) >= 2 then ' & More ' + cast(count(*) - 1 as varchar(255))
              else ''
         end)
        ) as ItemDisplayText
from t1 join
     (select t2.*,
             row_number() over (partition by categoryId order by ProductId desc) as seqnum
      from t2
     ) t2
     on t2.categoryId = t1.categoryId
group by t2.categoryId, t2.name;

答案 2 :(得分:0)

尝试这个:我们可以通过使用STUFF和TOP来获得表格的第一行。

CREATE TABLE #Table1(CategoryID INT, NAME VARCHAR(20))
INSERT INTO #Table1 VALUES  
(1,           'Fruits'), 
(2,           'Foods'),
(3,           'Drinks')

CREATE TABLE #Table2(ProductID INT, NAME VARCHAR(20), CategoryID INT)
INSERT INTO #Table2 VALUES
(1,           'Banana',      1),
(2,           'Mango',       1),
(3,           'Pineapple',   1),
(4,           'Whisky',      3),
(5,           'Water',       3)

- 以下代码以我们的要求格式选择所有匹配值

SELECT b.CategoryID,
    a.NAME,
    COUNT(b.ProductID) AS Items,
    STUFF((SELECT ',' + x.NAME FROM #table2 x
            WHERE x.CategoryID = b.CategoryID FOR XML PATH('')),1,1,'') As ItemDisplayText
FROM #Table2 b
INNER JOIN #Table1 a ON a.CategoryID = b.CategoryID
GROUP BY b.CategoryID, a.NAME

Output: CategoryID  NAME    Items   ItemDisplayText
        1           Fruits  3       Banana,Mango,Pineapple
        3           Drinks  2       Whisky,Water

- 这只是我们在输出中选择的一行

SELECT b.CategoryID,
    a.NAME,
    COUNT(b.ProductID) AS Items,
    STUFF((SELECT ',' + x.NAME FROM #table2 x
            WHERE x.CategoryID = b.CategoryID FOR XML PATH('')),1,1,'') As ItemDisplayText
FROM #Table2 b
INNER JOIN (SELECT TOP 1 * FROM #Table1 ORDER BY CategoryID) a ON a.CategoryID = b.CategoryID
GROUP BY b.CategoryID, a.NAME

Output: CategoryID  NAME    Items   ItemDisplayText
        1           Fruits  3       Banana,Mango,Pineapple

答案 3 :(得分:0)

我们走了

SELECT table1.*,count(t2.name) as items ,concat(derived.name, " and More ",count(t2.name)) as ItemDisplayText FROM 
        test.table1 join table2 t2 
            on table1.category = t2.category 
        join (select tab2.product,tab2.name,tab2.category from table2 tab2 where tab2.product = (select max(table2.product)from table2 where tab2.category = table2.category group by table2.category)) derived 
            on derived.category = t2.category
         -- where table1.category = 1 -- uncomment this if you want to filter with category id
    group by table1.category;

输出

category  name      items  ItemDisplayText
1         Fruits      3    Pineapple and More 3
3          Drinks     2    Water and More 2

我在mysql中试过这个,希望这在SQL-Server中有效。询问是否有任何疑问。