Cross-Sell Target Identifier
When launching a new product or looking to expand product adoption, sales teams need to identify which existing customers are most likely to purchase. This skill analyzes the characteristics of successful customers for a given product, finds similar customers who don't own it yet, and provides prioritized recommendations with justification.
Instructions
Step 1: Identify the Target Product
When user asks "Which customers should I pitch Product X to?":
- Identify the Product:
SELECT productid, name, description, producttypecode, productstructure FROM product WHERE name LIKE '%[product name]%' AND statecode = 0
- Confirm with user if multiple matches
Step 2: Analyze Successful Product X Customers
2.1 Find Customers Who Own Product X Query won opportunities that included the target product:
SELECT op.opportunityid, op.customerid, op.accountid, op.actualvalue, op.actualclosedate, op.salesstage FROM opportunity op JOIN opportunityproduct opp ON op.opportunityid = opp.opportunityid WHERE opp.productid = '[target_product_id]' AND op.statecode = 1
Note: A product may appear in multiple opportunityproduct rows per opportunity. Deduplicate opportunityids programmatically after fetching results.
2.2 Build Success Profile from Winning Accounts For each winning account, gather firmographic data:
SELECT accountid, name, industrycode, numberofemployees, revenue, customertypecode, address1_stateorprovince, address1_country, ownershipcode, createdon FROM account WHERE accountid IN ([list of winning account ids])
2.3 Analyze Success Patterns
Firmographic Analysis:
Calculate distribution across successful customers: - Industry breakdown (industrycode): Which industries buy most? - Company size (numberofemployees): What's the typical range? - Revenue range: What's the typical revenue bracket? - Geography (address1_stateorprovince/country): Regional concentrations? - Customer type (customertypecode): Are they customers, partners, etc.?
Existing Product Ownership:
For each successful customer, identify other products owned: SELECT a.accountid, a.name, p.name as product_name FROM account a JOIN opportunity o ON a.accountid = o.accountid JOIN opportunityproduct op ON o.opportunityid = op.opportunityid JOIN product p ON op.productid = p.productid WHERE o.statecode = 1 AND a.accountid IN ([winning account ids])
Buying Pattern Analysis:
Identify patterns in successful deals: - Average deal size for Product X - Common bundled products - Typical sales cycle length - Time since becoming customer before purchasing Product X
Activity Pattern Analysis:
Review activities preceding successful deals: - Types of engagement (calls, meetings, emails) - Number of touchpoints before close - Content/resources shared
Step 3: Generate Ideal Customer Profile (ICP)
Based on the analysis, create an Ideal Customer Profile:
IDEAL CUSTOMER PROFILE FOR [PRODUCT X] ════════════════════════════════════════════════════ FIRMOGRAPHIC CHARACTERISTICS: - Industry: [Top 3 industries, e.g., "Financial Services (35%), Healthcare (28%), Technology (22%)"] - Company Size: [Employee range, e.g., "100-500 employees (sweet spot)"] - Revenue: [Revenue range, e.g., "$10M-$100M annual revenue"] - Geography: [Regional patterns, e.g., "Primarily US, expanding to UK/EU"] BEHAVIORAL INDICATORS: - Already Owns: [Products commonly owned first, e.g., "80% have Product Y"] - Customer Tenure: [Time as customer, e.g., "Typically 6-18 months as customer"] - Recent Activity: [Engagement patterns, e.g., "High engagement with support/success"] - Expansion Signals: [Growth indicators, e.g., "Recent hiring, new funding"] BUYING PATTERNS: - Average Deal Size: [$X] - Typical Bundle: [Product X + Y + Z] - Sales Cycle: [X days average] - Common Champion: [Job title patterns] SUCCESS INDICATORS FROM NOTES: - Pain Points: [Common challenges mentioned] - Use Cases: [How they use the product] - Trigger Events: [What prompted purchase]
Step 4: Query Customer Base for Matches
4.1 Find Non-Owners of Product X
Note: Dataverse SQL does not support subqueries. Run two separate queries and exclude owners programmatically.
First, get all accounts that already own Product X (from Step 2.1 results — collect their accountids into a list).
Then query all active accounts:
SELECT a.accountid, a.name, a.industrycode, a.numberofemployees, a.revenue, a.customertypecode, a.address1_stateorprovince, a.createdon FROM account a WHERE a.statecode = 0
Filter out accounts whose accountid appears in the owner list programmatically after fetching.
4.2 Score Each Potential Target
For each non-owner account, calculate fit score:
Firmographic Fit (40%):
| Factor | Points | Scoring Logic |
|---|---|---|
| Industry Match | 0-15 | Exact match to top ICP industry = 15, Adjacent = 10, Other = 0 |
| Size Match | 0-15 | Within ICP range = 15, Close = 10, Outside = 5, Way off = 0 |
| Revenue Match | 0-10 | Within ICP range = 10, Close = 5, Outside = 0 |
Behavioral Fit (35%):
| Factor | Points | Scoring Logic |
|---|---|---|
| Owns Prerequisite Products | 0-15 | Has common prerequisite = 15, Related product = 10 |
| Customer Tenure | 0-10 | In ICP tenure range = 10, Close = 5 |
| Recent Engagement | 0-10 | High recent activity = 10, Moderate = 5, Low = 0 |
Buying Signals (25%):
| Factor | Points | Scoring Logic |
|---|---|---|
| Recent Purchases | 0-10 | Bought something in last 6 months = 10 |
| Expansion Behavior | 0-10 | Added users, upgraded = 10, Stable = 5 |
| Strategic Initiative Signals | 0-5 | Mentioned in notes/activities = 5 |
Step 5: Analyze Buying Signals
Important: Dataverse SQL Limitations Dataverse SQL does NOT support: subqueries, DATEADD(), GETUTCDATE(), HAVING, DISTINCT, UNION, CASE statements, AVG on sentiment. Calculate date filters programmatically before querying (e.g., '2025-09-01' for 6 months ago).
5.1 Recent Purchase Activity
SELECT a.accountid, a.name, o.opportunityid, o.name, o.actualclosedate, o.actualvalue FROM account a JOIN opportunity o ON a.accountid = o.accountid WHERE o.statecode = 1 AND o.actualclosedate > '2025-09-01'
5.2 Expansion Indicators Look for signals in activities and notes:
SELECT annotationid, objectid, subject, notetext, createdon FROM annotation WHERE objecttypecode = 'account' AND createdon > '2025-09-01'
Keywords to Detect:
- Expansion: "growing", "scaling", "expanding", "new offices", "hiring"
- Strategic: "initiative", "project", "transformation", "migration"
- Pain: "struggling", "challenge", "problem", "need"
- Competition: "evaluating", "considering", "looking at"
5.3 Recent Cases (Support Indicators) Query cases per account, then aggregate programmatically:
SELECT incidentid, customerid, createdon, prioritycode, msdyn_casesentiment FROM incident WHERE createdon >= '[6_months_ago]'
Group and count by customerid programmatically after fetching results.
High case volume could indicate:
- Active usage (good for expansion)
- Frustration (may need resolution first)
- Product limitations (potential for upsell to better solution)
Step 6: Rank and Present Target Accounts
Output Format:
CROSS-SELL TARGETS FOR [PRODUCT X] ════════════════════════════════════════════════════ Analysis Date: [Date] Methodology: Compared against [N] successful Product X customers SUMMARY: - Total Eligible Accounts: [N] - High Fit (Score 80+): [N] accounts - Medium Fit (Score 60-79): [N] accounts - Low Fit (Score <60): [N] accounts ════════════════════════════════════════════════════ TOP 10 CROSS-SELL TARGETS ════════════════════════════════════════════════════ 1. CONTOSO CORPORATION Fit Score: 92/100 ──────────────────────────────────────────────── WHY THEY'RE A FIT: ✓ Industry: Financial Services (top ICP industry) ✓ Size: 350 employees (in sweet spot 100-500) ✓ Already Owns: Product Y, Product Z (common prerequisite) ✓ Customer Since: 14 months (optimal tenure range) ✓ Recent Activity: 8 touchpoints in last 30 days BUYING SIGNALS DETECTED: • Mentioned "scaling operations" in recent meeting notes • Purchased add-on licenses last month (expansion behavior) • Attended Product X webinar 2 weeks ago RECOMMENDED APPROACH: • Lead with [specific value prop based on industry] • Reference success story from [similar customer] • Contact: [Primary contact name and role] ESTIMATED DEAL SIZE: $45,000 (based on similar deals) 2. FABRIKAM INDUSTRIES Fit Score: 87/100 ──────────────────────────────────────────────── WHY THEY'RE A FIT: ✓ Industry: Manufacturing (adjacent to ICP) ✓ Size: 800 employees (slightly above sweet spot) ✓ Already Owns: Product Y ✓ High engagement with Customer Success BUYING SIGNALS DETECTED: • New CTO joined 3 months ago (leadership change) • Mentioned "digital transformation" in discovery call POTENTIAL CONCERNS: ⚠ Above typical company size - may need enterprise approach ⚠ No activity with Sales in last 60 days RECOMMENDED APPROACH: • Re-engage through Customer Success warm intro • Position as part of transformation initiative • Consider executive sponsor engagement [Continue for top 10...]
Step 7: Create Action Items
Generate Follow-up Tasks:
For each top target, offer to create: Use create_record with tablename: task { "subject": "Cross-sell outreach: [Product X] to [Account Name]", "description": "Target identified as high fit for [Product X].\n\nFit Score: [X]/100\n\nKey talking points:\n- [Point 1]\n- [Point 2]\n\nContact: [Recommended contact]", "regardingobjectid": "[accountid]", "scheduledend": "[appropriate date]", "prioritycode": [based on fit score] }
Update Account with Cross-Sell Flag:
Consider adding notes to account: Use create_record with tablename: annotation { "subject": "Cross-sell opportunity identified: [Product X]", "notetext": "[Summary of why they're a fit and recommended approach]", "objectid": "[accountid]", "objecttypecode": "account" }
Dataverse Tables Used
| Table | Purpose |
|---|---|
product | Identify target product |
opportunity | Find won deals with target product |
opportunityproduct | Link opportunities to products |
account | Customer firmographic data |
contact | Stakeholder information |
activitypointer | Engagement history |
annotation | Notes containing buying signals |
incident | Support case patterns |
task | Create follow-up tasks |
Key Fields Reference
product:
productid(GUID) - Unique identifiername(NVARCHAR) - Product nameproductnumber(NVARCHAR) - SKU/product numberproducttypecode(CHOICE) - Sales Inventory(1), Misc Charges(2), Services(3), Flat Fees(4)productstructure(CHOICE) - Product(1), Family(2), Bundle(3)statecode(STATE) - Active(0), Retired(1), Draft(2), Under Revision(3)
opportunity:
accountid(LOOKUP → account) - Related accountstatecode(STATE) - Open(0), Won(1), Lost(2)statuscode(STATUS) - In Progress(1), On Hold(2) [Open]; Won(3) [Won]; Canceled(4), Out-Sold(5) [Lost]actualvalue(MONEY) - Won deal valueactualclosedate(DATE) - When deal closedoriginatingleadid(LOOKUP → lead) - Source lead
opportunityproduct:
opportunityid(LOOKUP → opportunity) - Parent opportunityproductid(LOOKUP → product) - Product in the dealquantity(DECIMAL) - Units soldpriceperunit(MONEY) - Unit priceextendedamount(MONEY) - Line total (calculated)manualdiscountamount(MONEY) - Line discount
account:
industrycode(CHOICE) - Accounting(1), Agriculture(2), Broadcasting(3), Brokers(4), Building Supply(5), Business Services(6), Consulting(7), Consumer Services(8), etc.numberofemployees(INT) - Company sizerevenue(MONEY) - Annual revenuecustomertypecode(CHOICE) - Customer classificationopenrevenue(MONEY) - Total open pipeline value (rollup field; availability depends on org configuration — query opportunity table directly if not present)opendeals(INT) - Number of open opportunities (rollup field; availability depends on org configuration)
Cross-Sell Best Practices
- Start with success: Always analyze existing successful customers first
- Multi-factor matching: Don't rely on single criteria for fit
- Watch for timing: Recent purchases indicate budget availability
- Leverage relationships: Warm introductions beat cold outreach
- Segment recommendations: Different approaches for different segments
- Track results: Monitor conversion rates to refine the model
Examples
Example 1: Find Cross-Sell Targets for New Product
User says: "Who should I pitch our new Analytics Pro product to?"
Actions:
- Search product table for "Analytics Pro"
- Find accounts that have purchased Analytics Pro
- Build ideal customer profile from successful accounts
- Query non-owners matching the profile
- Rank by fit score and provide recommendations
Result:
IDEAL CUSTOMER PROFILE FOR ANALYTICS PRO: - Industry: Financial Services (45%), Healthcare (30%) - Size: 200-1000 employees - Already owns: Platform Basic (80% correlation) TOP 10 CROSS-SELL TARGETS: 1. Northwind Bank (92% fit) - Financial Services, 450 employees, owns Platform Basic 2. Alpine Health (87% fit) - Healthcare, 800 employees, recent support engagement
Example 2: Upsell Existing Customers
User says: "Which customers should upgrade to Enterprise tier?"
Actions:
- Identify customers on lower tiers
- Analyze Enterprise customers for common traits
- Find Standard tier customers matching Enterprise profile
- Factor in engagement and growth signals
Result:
UPGRADE CANDIDATES (Standard → Enterprise): 1. Contoso Ltd - Growing usage, added 50 users last quarter 2. Fabrikam Inc - Multiple support cases about feature limits 3. Tailspin Toys - Recent funding, headcount doubling
Example 3: Product Bundle Opportunity
User says: "Who bought Product A but not Product B?"
Actions:
- Find accounts with Product A in won opportunities
- Exclude accounts with Product B in won opportunities
- Rank by recency and relationship strength
Result:
PRODUCT A CUSTOMERS WITHOUT PRODUCT B: - 23 accounts identified - Average fit score: 78% - Top 5 recommendations with outreach scripts provided
Troubleshooting
Error: Product not found
Cause: Product name doesn't match exactly or product is inactive Solution:
- Search with partial name match (LIKE '%name%')
- Check statecode to include active products only
- List available products for user to select
Error: No customers found for target product
Cause: New product with no sales history yet Solution:
- Use similar product's customer base as proxy
- Define ideal customer profile manually
- Start with industry/size matching only
Error: Too few differentiation signals
Cause: Winning customers too diverse for clear pattern Solution:
- Increase sample size (longer date range)
- Focus on top-performing accounts only
- Add firmographic filters (industry, size)


