SQL SELECT:创建一个列,用于计算以特定字母开头的sub_categories数

时间:2015-01-15 10:46:21

标签: mysql sql

我正在使用的查询如下。我需要在我的结果中使用一个名为letter_count的第四列,它计算有多少个子类别以A开头,有多少以B开头,等等一直到Z--如果这可以动态完成而不是为每个添加一行,那将更为可取。信。

我正在寻找的表/结果示例显示在此问题的底部。我无法弄清楚如何修改查询以获得第4列。

SELECT 
     headings.heading AS sub_category, 
    LEFT( headings.heading, 1 ) AS first_letter, 
    headings.url_code as url_code 
FROM TOWN_TABLE a 
    INNER JOIN headings ON a.Heading=headings.heading 
WHERE Category = 'Classified'
GROUP BY sub_category
ORDER BY sub_category ASC

结果:

+-------------------------+--------------+-------------------------+--+
|      sub_category       | first_letter |        url_code         | letter_count |
+-------------------------+--------------+-------------------------+--+
| Accountants             | A            | accountants             | 6 |
| Adult Education         | A            | adult education         | 6 |
| Aerials                 | A            | aerials                 | 6 |
| Alarms                  | A            | alarms                  | 6 |
| Architectural Services  | A            | architectural services  | 6 |
| Art & Craft             | A            | art and craft           | 6 |
| Bathrooms               | B            | bathrooms               | 8 |
| Beauty Salons & Therapy | B            | beauty salons & therapy | 8 |
| Bed & Breakfast         | B            | bed and breakfast       | 8 |
| Bedrooms                | B            | bedrooms                | 8 |
| Boiler Maintenance      | B            | boiler maintenance      | 8 |
| Bookkeeping Services    | B            | bookkeeping services    | 8 |
| Builders                | B            | builders                | 8 |
| Builders Merchants      | B            | builders merchants      | 8 |
+-------------------------+--------------+-------------------------+--+

3 个答案:

答案 0 :(得分:1)

您需要创建一个派生表,该表按第一个字母分组以获取您的计数,然后将其加入到原始表中。它变得更加混乱,因为你有几个headings想看的条件。如果这不能立即工作,我建议删除WHERE并让它在没有它的情况下工作,这样你就能理解结构,然后再添加WHERE。

SELECT headings.heading AS sub_category, 
       LEFT( headings.heading, 1 ) AS first_letter, 
       headings.url_code as url_code , 
       letter_counts.letter_count
FROM headings ON a.Heading=headings.heading 
INNER JOIN ( 
      -- make a derived table of each letter and how many 
      -- headings start with it. Only count ones that have
      -- a TOWN_TABLE entry with category Classified.
      select left(h_all.heading,1) as the_letter, 
             count(*) as letter_count
      from headings h_all
      WHERE EXISTS ( select * from TOWN_TABLE t 
                     where t.heading = h_all.heading 
                     AND Category = 'Classified') 
      group by left(h_all.heading,1)
    ) as letter_counts on left(heading.heading,1) = letter_counts.the_letter
WHERE EXISTS ( select * from TOWN_TABLE t 
               where t.heading = headings.heading 
               AND Category = 'Classified') 
order by headings.heading

或者在SQL Server中,您可以使用CTE使其略微更好地阅读。不确定CTE是否在mysql中工作:

with sub_categories ( first_letter, sub_category ) 
as ( 
     select left( h.heading, 1 ) 
          , h.heading
     from headings h
     where exists( select * from TOWN_TABLE t 
                    where t.heading = h_all.heading 
                    and Category = 'Classified') 
) 
select sc.sub_category
     , sc.first_letter
     , sub_category_counts.the_count
from sub_categories sc
inner join ( 
    select first_letter
         , count(*) as the_count
    from sub_categories
    group by first_letter
) as sub_category_counts on sub_category_counts.first_letter = sc.first_letter
order by sc.sub_category

答案 1 :(得分:1)

我认为这应该有效:

SELECT 
     headings.heading AS sub_category, 
    LEFT( headings.heading, 1 ) AS first_letter, 
    headings.url_code as url_code , CNT as letter_count
FROM TOWN_TABLE a 
    INNER JOIN headings ON a.Heading=headings.heading 
INNER JOIN (SELECT LEFT( headings.heading, 1 ) AS first_letter, COUNT(DISTINCT LEFT( headings.heading, 1 )) as CNT FROM headings) AS lettercounts
ON lettercounts.first_letter = LEFT( headings.heading, 1 )
WHERE Category = 'Classified'
GROUP BY sub_category
ORDER BY sub_category ASC;

答案 2 :(得分:1)

您可以添加联接字段:

SELECT
    ...,
    ( SELECT COUNT(*) FROM headings AS lett 
          WHERE LEFT(lett.heading, 1)=first_letter)
    AS letter_count
FROM ...

这应该从外部查询中获取first_letter并计算从该字母开始的标题数。如果它不起作用,因为first_letter是别名,您需要明确说明其值:

    ( SELECT COUNT(*) FROM headings AS lett 
          WHERE LEFT(lett.heading, 1)=LEFT(headings.heading, 1))
    AS letter_count

您使用headings两次,一次获取您需要的数据,第二次获取第一个字母。

This是用于测试目的的SQL小提琴的链接

SUB_CATEGORY    FIRST_LETTER    URL_CODE            LETTER_COUNT
Accountants     A               /url/accountants    2
Art & Craft     A               /url/arts_crafts    2
Bathrooms       B               /url/bathrooms      1