diff --git a/apps/www/components/SurveyResults/charts/AICodingToolsChart.tsx b/apps/www/components/SurveyResults/charts/AICodingToolsChart.tsx index 771967b3a1d..00525cc720b 100644 --- a/apps/www/components/SurveyResults/charts/AICodingToolsChart.tsx +++ b/apps/www/components/SurveyResults/charts/AICodingToolsChart.tsx @@ -3,14 +3,37 @@ import { SurveyChart, buildWhereClause } from '../SurveyChart' function generateAICodingToolsSQL(activeFilters: Record) { const whereClause = buildWhereClause(activeFilters) - return ` -SELECT - unnest(ai_coding_tools) AS technology, - COUNT(*) AS total -FROM responses_c_2025${whereClause ? '\n' + whereClause : ''} -GROUP BY technology -ORDER BY total DESC; -` + return `WITH ai_coding_tools_mapping AS ( + SELECT + id, + CASE + WHEN technology IN ( + 'Cursor', + 'Windsurf', + 'Cline', + 'Visual Studio Code', + 'Lovable', + 'Bolt', + 'v0', + 'Tempo', + 'None' + ) THEN technology + WHEN LOWER(technology) LIKE '%claude%' THEN 'Claude or Claude Code' + WHEN LOWER(technology) = 'chatgpt' THEN 'ChatGPT' + ELSE 'Other' + END AS technology_clean + FROM ( + SELECT id, unnest(ai_coding_tools) AS technology + FROM responses_2025 + ${whereClause} + ) sub + ) + SELECT + technology_clean AS technology, + COUNT(DISTINCT id) AS total + FROM ai_coding_tools_mapping + GROUP BY technology_clean + ORDER BY total DESC;` } export function AICodingToolsChart() { diff --git a/apps/www/components/SurveyResults/charts/AIModelsChart.tsx b/apps/www/components/SurveyResults/charts/AIModelsChart.tsx index ed630ffc953..fde69394ee2 100644 --- a/apps/www/components/SurveyResults/charts/AIModelsChart.tsx +++ b/apps/www/components/SurveyResults/charts/AIModelsChart.tsx @@ -3,12 +3,36 @@ import { SurveyChart, buildWhereClause } from '../SurveyChart' function generateAIModelsSQL(activeFilters: Record) { const whereClause = buildWhereClause(activeFilters) - return `SELECT - unnest(ai_models_used) AS model, - COUNT(*) AS total -FROM responses_c_2025${whereClause ? '\n' + whereClause : ''} -GROUP BY model -ORDER BY total DESC;` + return `WITH ai_models_used_mapping AS ( + SELECT + id, + CASE + WHEN technology IN ( + 'OpenAI', + 'Anthropic/Claude', + 'Hugging Face', + 'Custom models', + 'SageMaker', + 'Bedrock', + 'Cohere', + 'Mistral' + ) THEN technology + WHEN LOWER(technology) LIKE '%gemini%' THEN 'Gemini' + WHEN LOWER(technology) = 'deepseek' THEN 'DeepSeek' + ELSE 'Other' + END AS technology_clean + FROM ( + SELECT id, unnest(ai_models_used) AS technology + FROM responses_2025 + ${whereClause} + ) sub + ) + SELECT + technology_clean AS technology, + COUNT(DISTINCT id) AS total + FROM ai_models_used_mapping + GROUP BY technology_clean + ORDER BY total DESC;` } export function AIModelsChart() { diff --git a/apps/www/components/SurveyResults/charts/AcceleratorParticipationChart.tsx b/apps/www/components/SurveyResults/charts/AcceleratorParticipationChart.tsx index 70c0b90c185..cb17c715db3 100644 --- a/apps/www/components/SurveyResults/charts/AcceleratorParticipationChart.tsx +++ b/apps/www/components/SurveyResults/charts/AcceleratorParticipationChart.tsx @@ -11,7 +11,7 @@ function generateAcceleratorParticipationSQL(activeFilters: Record) { const whereClause = buildWhereClause(activeFilters, ['biggest_challenge IS NOT NULL']) @@ -13,7 +12,7 @@ function generateBiggestChallengeSQL(activeFilters: Record) { WHEN biggest_challenge IN ('Customer acquisition', 'Technical complexity', 'Product-market fit', 'Product-market fit', 'Fundraising', 'Hiring', 'Other') THEN biggest_challenge ELSE 'Other' END AS biggest_challenge_clean - FROM responses_c_2025 + FROM responses_2025 ${whereClause} ) SELECT diff --git a/apps/www/components/SurveyResults/charts/DatabasesChart.tsx b/apps/www/components/SurveyResults/charts/DatabasesChart.tsx index 6504a6f2b92..805281a8cf0 100644 --- a/apps/www/components/SurveyResults/charts/DatabasesChart.tsx +++ b/apps/www/components/SurveyResults/charts/DatabasesChart.tsx @@ -3,12 +3,33 @@ import { SurveyChart, buildWhereClause } from '../SurveyChart' function generateDatabasesSQL(activeFilters: Record) { const whereClause = buildWhereClause(activeFilters) - return `SELECT - unnest(databases) AS technology, - COUNT(*) AS total -FROM responses_c_2025${whereClause ? '\n' + whereClause : ''} -GROUP BY technology -ORDER BY total DESC;` + return `WITH database_mapping AS ( + SELECT + id, + CASE + WHEN technology IN ( + 'Supabase', + 'PostgreSQL', + 'MySQL', + 'MongoDB', + 'Redis', + 'Firebase', + 'SQLite' + ) THEN technology + ELSE 'Other' + END AS technology_clean + FROM ( + SELECT id, unnest(databases) AS technology + FROM responses_2025 + ${whereClause} + ) sub + ) + SELECT + technology_clean AS technology, + COUNT(DISTINCT id) AS total + FROM database_mapping + GROUP BY technology_clean + ORDER BY total DESC;` } export function DatabasesChart() { diff --git a/apps/www/components/SurveyResults/charts/FrontendStackChart.tsx b/apps/www/components/SurveyResults/charts/FrontendStackChart.tsx index 5c4b04f4779..445c833d3e3 100644 --- a/apps/www/components/SurveyResults/charts/FrontendStackChart.tsx +++ b/apps/www/components/SurveyResults/charts/FrontendStackChart.tsx @@ -6,7 +6,7 @@ function generateFrontendStackSQL(activeFilters: Record) { return `SELECT unnest(frontend_stack) AS technology, COUNT(*) AS total -FROM responses_c_2025${whereClause ? '\n' + whereClause : ''} +FROM responses_2025${whereClause ? '\n' + whereClause : ''} GROUP BY technology ORDER BY total DESC; ` diff --git a/apps/www/components/SurveyResults/charts/FundingStageChart.tsx b/apps/www/components/SurveyResults/charts/FundingStageChart.tsx index f667dd88eaf..765fd49064f 100644 --- a/apps/www/components/SurveyResults/charts/FundingStageChart.tsx +++ b/apps/www/components/SurveyResults/charts/FundingStageChart.tsx @@ -6,7 +6,7 @@ function generateFundingStageSQL(activeFilters: Record) { return `SELECT funding_stage, COUNT(*) AS total - FROM responses_c_2025${whereClause ? '\n' + whereClause : ''} + FROM responses_2025${whereClause ? '\n' + whereClause : ''} GROUP BY funding_stage ORDER BY CASE WHEN funding_stage = 'Bootstrapped' THEN 1 diff --git a/apps/www/components/SurveyResults/charts/IndustryChart.tsx b/apps/www/components/SurveyResults/charts/IndustryChart.tsx index 09e4eb6e684..53e0e9a61b4 100644 --- a/apps/www/components/SurveyResults/charts/IndustryChart.tsx +++ b/apps/www/components/SurveyResults/charts/IndustryChart.tsx @@ -1,6 +1,5 @@ import { SurveyChart, buildWhereClause } from '../SurveyChart' -// Generate SQL query for team count chart function generateIndustrySQL(activeFilters: Record) { const whereClause = buildWhereClause(activeFilters, ['industry IS NOT NULL']) @@ -13,7 +12,7 @@ function generateIndustrySQL(activeFilters: Record) { WHEN industry IN ('SaaS', 'Dev tools', 'AI / ML', 'Consumer', 'Education', 'eCommerce', 'Fintech', 'Healthtech') THEN industry ELSE 'Other' END AS industry_clean - FROM responses_c_2025 + FROM responses_2025 ${whereClause} ) SELECT diff --git a/apps/www/components/SurveyResults/charts/InitialPayingCustomersChart.tsx b/apps/www/components/SurveyResults/charts/InitialPayingCustomersChart.tsx index ef2b8bcd356..7d843293596 100644 --- a/apps/www/components/SurveyResults/charts/InitialPayingCustomersChart.tsx +++ b/apps/www/components/SurveyResults/charts/InitialPayingCustomersChart.tsx @@ -3,15 +3,34 @@ import { SurveyChart, buildWhereClause } from '../SurveyChart' function generateInitialPayingCustomersSQL(activeFilters: Record) { const whereClause = buildWhereClause(activeFilters) - return `SELECT - source, - COUNT(DISTINCT id) AS respondents -FROM ( - SELECT id, unnest(initial_paying_customers) AS source - FROM responses_c_2025${whereClause ? '\n' + whereClause : ''} -) sub -GROUP BY source -ORDER BY respondents DESC;` + return `WITH customer_source_mapping AS ( + SELECT + id, + CASE + WHEN source IN ( + 'Personal/professional network', + 'Inbound from social media (Twitter, LinkedIn, etc.)', + 'Cold outreach or sales', + 'Content (blog, newsletter, SEO)', + 'Developer communities (Discord, Slack, Reddit, etc.)', + 'Open source users who converted', + 'Accelerators/incubators', + 'Hacker News or Product Hunt' + ) THEN source + ELSE 'Other' + END AS source_clean + FROM ( + SELECT id, unnest(initial_paying_customers) AS source + FROM responses_2025 + ${whereClause} + ) sub + ) + SELECT + source_clean AS source, + COUNT(DISTINCT id) AS respondents + FROM customer_source_mapping + GROUP BY source_clean + ORDER BY respondents DESC;` } export function InitialPayingCustomersChart() { diff --git a/apps/www/components/SurveyResults/charts/LocationChart.tsx b/apps/www/components/SurveyResults/charts/LocationChart.tsx index 1641873c534..b499579d2e5 100644 --- a/apps/www/components/SurveyResults/charts/LocationChart.tsx +++ b/apps/www/components/SurveyResults/charts/LocationChart.tsx @@ -6,7 +6,7 @@ function generateLocationSQL(activeFilters: Record) { return `SELECT location, COUNT(*) AS total -FROM responses_c_2025${whereClause ? '\n' + whereClause : ''} +FROM responses_2025${whereClause ? '\n' + whereClause : ''} GROUP BY location ORDER BY total DESC;` } diff --git a/apps/www/components/SurveyResults/charts/NewIdeasChart.tsx b/apps/www/components/SurveyResults/charts/NewIdeasChart.tsx index 148b1afd9d4..04d32d11aed 100644 --- a/apps/www/components/SurveyResults/charts/NewIdeasChart.tsx +++ b/apps/www/components/SurveyResults/charts/NewIdeasChart.tsx @@ -1,20 +1,38 @@ import { SurveyChart, buildWhereClause } from '../SurveyChart' function generateNewIdeasSQL(activeFilters: Record) { - const whereClause = buildWhereClause(activeFilters, [ - 'must_have_dev_tools IS NOT NULL', - "must_have_dev_tools != ''", - ]) + const whereClause = buildWhereClause(activeFilters) - return `SELECT - avenue, - COUNT(DISTINCT id) AS respondents -FROM ( - SELECT id, unnest(new_ideas) AS avenue - FROM responses_c_2025${whereClause ? '\n' + whereClause : ''} -) sub -GROUP BY avenue -ORDER BY respondents DESC;` + return `WITH new_ideas_mapping AS ( + SELECT + id, + CASE + WHEN avenue IN ( + 'Hacker News', + 'GitHub', + 'Product Hunt', + 'Twitter/X', + 'Reddit', + 'YouTube', + 'Podcasts', + 'Blogs / Newsletters', + 'Discord / Slack communities', + 'Conferences / Meetups' + ) THEN avenue + ELSE 'Other' + END AS avenue_clean + FROM ( + SELECT id, unnest(new_ideas) AS avenue + FROM responses_2025 + ${whereClause} + ) sub + ) + SELECT + avenue_clean AS avenue, + COUNT(DISTINCT id) AS total + FROM new_ideas_mapping + GROUP BY avenue_clean + ORDER BY total DESC;` } export function NewIdeasChart() { diff --git a/apps/www/components/SurveyResults/charts/RegularSocialMediaUseChart.tsx b/apps/www/components/SurveyResults/charts/RegularSocialMediaUseChart.tsx index 90b2efe9e29..67305a3df6b 100644 --- a/apps/www/components/SurveyResults/charts/RegularSocialMediaUseChart.tsx +++ b/apps/www/components/SurveyResults/charts/RegularSocialMediaUseChart.tsx @@ -3,29 +3,39 @@ import { SurveyChart, buildWhereClause } from '../SurveyChart' function generateRegularSocialMediaUseSQL(activeFilters: Record) { const whereClause = buildWhereClause(activeFilters) - return `WITH founders AS ( - SELECT id, regular_social_media_use - FROM responses_c_2025${whereClause ? '\n' + whereClause : ''} -) -SELECT - platform AS label, - COUNT(*) AS total -FROM ( - SELECT id, unnest(regular_social_media_use) AS platform - FROM founders -) t -GROUP BY platform -ORDER BY total DESC; -` + return `WITH regular_social_media_use_mapping AS ( + SELECT + id, + CASE + WHEN platform IN ( + 'X (Twitter)', + 'Threads', + 'BlueSky', + 'LinkedIn', + 'Reddit', + 'TikTok', + 'Instagram', + 'YouTube', + 'Mastodon', + 'Discord', + 'I’ve given up social media' + ) THEN platform + ELSE 'Other' + END AS platform_clean + FROM ( + SELECT id, unnest(regular_social_media_use) AS platform + FROM responses_2025 + ${whereClause} + ) sub + ) + SELECT + platform_clean AS platform, + COUNT(DISTINCT id) AS total + FROM regular_social_media_use_mapping + GROUP BY platform_clean + ORDER BY total DESC;` } -// SELECT -// unnest(regular_social_media_use) AS social_media, -// COUNT(*) AS total -// FROM responses_c_2025${whereClause ? '\n' + whereClause : ''} -// GROUP BY social_media -// ORDER BY total DESC; - export function RegularSocialMediaUseChart() { return ( ) { const whereClause = buildWhereClause(activeFilters) @@ -11,7 +10,7 @@ function generateRoleSQL(activeFilters: Record) { ELSE 'Other' END AS role, COUNT(*) AS total -FROM responses_c_2025${whereClause ? '\n' + whereClause : ''} +FROM responses_2025${whereClause ? '\n' + whereClause : ''} GROUP BY CASE WHEN role = 'Founder / Co-founder' THEN 'Founder' WHEN role IN ('Engineer', 'Founder / Co-founder') THEN role @@ -21,13 +20,6 @@ ORDER BY total DESC; ` } -// SELECT -// person_role_normalized, -// COUNT(*) AS total -// FROM responses_c_2025${whereClause ? '\n' + whereClause : ''} -// GROUP BY person_role_normalized -// ORDER BY total DESC - export function RoleChart() { return ( ) { const whereClause = buildWhereClause(activeFilters) - return ` + return `WITH customer_tool_mapping AS ( + SELECT + id, + CASE + WHEN tool IN ( + 'HubSpot', + 'Salesforce', + 'Pipedrive', + 'Close.com', + 'Notion / Airtable', + 'Google Sheets', + 'We don’t have a formal CRM or sales tool yet' + ) THEN tool + ELSE 'Other' + END AS tool_clean + FROM ( + SELECT id, unnest(sales_tools) AS tool + FROM responses_2025 + ${whereClause} + ) sub + ) SELECT - unnest(sales_tools) AS tool_name, - COUNT(*) AS total -FROM responses_c_2025${whereClause ? '\n' + whereClause : ''} -GROUP BY tool_name -ORDER BY total DESC; -` + tool_clean AS tool, + COUNT(DISTINCT id) AS respondents + FROM customer_tool_mapping + GROUP BY tool_clean + ORDER BY respondents DESC;` } export function SalesToolsChart() { diff --git a/apps/www/components/SurveyResults/charts/WorldOutlookChart.tsx b/apps/www/components/SurveyResults/charts/WorldOutlookChart.tsx index 4988ac9609c..dddcbed0dc4 100644 --- a/apps/www/components/SurveyResults/charts/WorldOutlookChart.tsx +++ b/apps/www/components/SurveyResults/charts/WorldOutlookChart.tsx @@ -1,6 +1,5 @@ import { SurveyChart, buildWhereClause } from '../SurveyChart' -// Generate SQL query for team count chart function generateWorldOutlookSQL(activeFilters: Record) { const whereClause = buildWhereClause(activeFilters) @@ -8,7 +7,7 @@ function generateWorldOutlookSQL(activeFilters: Record) { world_outlook, COUNT(*) AS total --ROUND(100.0 * COUNT(*) / SUM(COUNT(*)) OVER (), 2) AS percentage -FROM responses_c_2025${whereClause ? '\n' + whereClause : ''} +FROM responses_2025${whereClause ? '\n' + whereClause : ''} GROUP BY world_outlook ORDER BY total DESC;` }