【问题标题】:Is it possible to group unlike items and count them together?是否可以将不同的项目分组并将它们一起计数?
【发布时间】:2013-04-03 21:29:51
【问题描述】:

给定下表:

Chain    Name
123      Company 1
124      Other Company 1
123      Whatever Company
125      This One
126      That One
125      Another One
127      Last One

当我在 Chain 列上执行 Count 时,我得到以下结果:

123      2
124      1
125      2
126      1
127      1

是否可以将链 123 和 124 分组以便一起计算?还有125和126组吗?修改后的结果如下所示:

123/124  3
125/126  3
127      1

我的 SQL 如下所示:

SELECT Table1.Chain, Count(*) as [Count]
FROM Table1 LEFT JOIN Table2 on Table1.Chain = Table2.Chain
WHERE (((Table1.Chain) IN (Table2.Chain)))
GROUP BY Table1.Chain
ORDER BY Table1.Chain;

谢谢!

【问题讨论】:

    标签: sql ms-access


    【解决方案1】:

    根据您的需要,这可能有点麻烦,但我可能会添加一个表来存储您正在寻找的链和链组。像这样的:

    Chain  ChainGroup
    123      123/124
    124      123/124
    125      125/126
    126      125/126
    127      127/128
    

    然后,在查询中,我将加入此表,而不是按 Chain 分组,而是按 ChainGroup 分组。

    我更喜欢嵌套 IIF 语句之类的东西,因为它们很难调试,而且将来您可能会有额外的分组,这些分组很容易添加到表中并自动出现新分组在查询中。

    【讨论】:

    • 好电话。比我的回答更有意义!
    【解决方案2】:

    是的,您可以:

    SELECT min(Table1.Chain) & '/' & max(Table1.Chain) as chain, Count(*) as [Count]
    FROM Table1 LEFT JOIN Table2 on Table1.Chain = Table2.Chain
    WHERE (((Table1.Chain) IN (Table2.Chain)))
    GROUP BY int((Table1.Chain-1)/2)
    ORDER BY min(Table1.Chain);
    

    【讨论】:

    • 让我知道您是否尝试过,效果如何?
    【解决方案3】:

    您可以使用嵌套的Iif 语句。希望我的括号都在下面! :-)

    SELECT Iif(Table1.Chain="123", "123/124",
             Iif(Table1.Chain="124", "123/124",
               Iif(Table1.Chain="125", "125/126",
                 Iif(Table1.Chain="126", "125/126", Table1.Chain)))) as [Chain]
     , Count(*) as [Count]
    FROM Table1 LEFT JOIN Table2 on Table1.Chain = Table2.Chain
    WHERE (((Table1.Chain) IN (Table2.Chain)))
    GROUP BY Iif(Table1.Chain="123", "123/124",
               Iif(Table1.Chain="124", "123/124",
                 Iif(Table1.Chain="125", "125/126",
                   Iif(Table1.Chain="126", "125/126", Table1.Chain))))
    ORDER BY Table1.Chain;
    

    如果您不想在查询中写两次,也可以将 case 语句移动到 from 子句中的子查询或公用表表达式中。

    【讨论】:

    • 我从来不知道你可以这样使用case!我会试一试..谢谢!
    • 好主意,但我不相信 MS Access 支持查询中的 CASE 语句...可能需要改为使用嵌套的 IIF 语句。
    • @JeffBrady 因为您使用的是 Access,所以不能这样做。您需要改用 Iif。我将编辑我的答案。
    • 嵌套的IIf 表达式变得具有挑战性。请考虑使用Switch 表达式:stackoverflow.com/a/15776608/77335
    • 在 Access SQL 中,您可以简单地说 GROUP BY [Chain]ORDER BY [Chain]。不过,老实说,我会推荐 Tim 的解决方案。
    【解决方案4】:

    考虑类似:

    SELECT
    chain_group, COUNT(*) FROM (
    SELECT 
    Table1.Chain, 
    switch(Table1.Chain IN("123","124"), "123/124",
    Table1.Chain IN("125","126"),"125/126",
    Table1.Chain) AS chain_group
    FROM 
    Table1 INNER JOIN 
    Table2 ON 
    Table1.Chain = Table2.Chain) t
    GROUP BY chain_group
    ORDER BY chain_group
    

    【讨论】:

    • 这给出了一个错误Wrong number of arguements used with function in query expression 'Iif(Table1.Chain IN("123","124"), "123/124", Table1.Chain IN("125","126"),"125/126", Table1.Chain
    • 对不起,应该使用'switch'功能而不是IIF
    • 谢谢..我试试看!
    【解决方案5】:

    你可以看下面的例子 ----- 制作主表

    CREATE TABLE #test 
    ( id int , Name varchar(100))
    
    INSERT #test(id,Name)
    values (123,'Company 1'),
    (124,'Other Company 1'),
    (123,      'Whatever Company'),
    (125,      'This One'),
    (126 ,     'That One'),
    (125,      'Another One'),
    (127,      'Last One')
    
    CREATE TABLE #temp
    (rowID INT IDENTITY(1,1) , ID INT ,cnt INT )
    
    CREATE TABLE #tempResult
    (ID VARCHAR(20) ,cnt INT )
    
    INSERT INTO #temp(ID,cnt)
    SELECT  ID ,COUNT(1) cnt FROM  #test GROUP BY ID 
    
    DECLARE @rowCnt INT , @TotalCnt INT , @even INT , @odd INT , 
    @idNum VARCHAR(20) , @valueCnt INT , @inStart INT = 1
    
    SET @rowCnt  = 1
    SET @even = 1 
    SET @odd = 2
    
    SELECT @TotalCnt = COUNT(1) FROM #temp
    
    WHILE @rowCnt <= @TotalCnt
    BEGIN
        SET @inStart = 1
        SET @odd = @rowCnt 
        SET @even = @rowCnt + 1
        SET @idNum = ''
        SET @valueCnt = 0
    
        WHILE @inStart <= 2
        BEGIN
    
        IF @inStart = 1
        Begin
         SELECT @idNum = Convert(VARCHAR(5),ID) , @valueCnt = cnt 
         FROM #temp WHERE rowID = @odd
        End 
        ELSE
        BEGIN
        SELECT @idNum = @idNum + '/' + Convert(VARCHAR(5),ID) , @valueCnt = @valueCnt  + cnt 
    FROM #temp WHERE rowID = @even  
        END
            SET @inStart = @inStart + 1
        END
        INSERT INTO #tempResult (ID, Cnt) 
        VALUES (@idNum,@valueCnt)
    
        SET @rowCnt = @rowCnt + 2
    END
    
    SELECT *
    FROM #tempResult
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-03-27
      • 1970-01-01
      • 1970-01-01
      • 2014-04-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多