2

I wrote a query which uses two columns and each of those columns come from different tables. How can I make an index for these columns and is it even possible?

select countryName, balance
from main.country c 
join main.person p on (c.countryId = p.countryId)
where balance = (select MAX(balance) 
                 from main.person p2 
                 join main.country c2 on (c2.countryId = p2.countryId)
                 where c.countryId = c2.countryId 
                   and p.countryId = p2.countryId)
order by countryName;
4
  • Your question seems to be a duplicate of stackoverflow.com/questions/8509026/…. Commented May 26, 2018 at 0:03
  • For some reason sql doesn't allow me to join these tables create index idx_countryperson on main.country c inner join main.person p on c.countryId=p.countryId(c.countryName, p.balance); Commented May 26, 2018 at 0:31
  • 1
    Not sql! The product is called SQL Server! SQL is a language used by numerous relational database management systems. SQL Server is only on of them. Others include Oracle, MySQL, PostgreSQL, MariaDB, to name a few. Commented May 26, 2018 at 1:21
  • 1
    Ok, I'll know from now on Commented May 26, 2018 at 1:22

2 Answers 2

3

In SQL Server, if you want to create an index on columns from different tables, then you can create a Schema Bound View and build your index on top of that view.

In you case, create a schema bound view:

CREATE VIEW MyBoundView
WITH SCHEMABINDING  
AS  
   -- YOU QUERY 
   select countryName, balance
   from main.country c join main.person p on(c.countryId=p.countryId)
   where balance=(select MAX(balance) from main.person p2 join main.country c2 
   on(c2.countryId=p2.countryId)
   where c.countryId=c2.countryId and p.countryId=p2.countryId)
   order by countryName;  

GO  

Now you can create an index with your two columns on this bound view:

--Example index on the bound view.  
CREATE UNIQUE CLUSTERED INDEX IDX_V1   
   ON MyBoundView (countryName, balance);  
GO  

You may find this article useful.

Sign up to request clarification or add additional context in comments.

Comments

1

This is your query:

select countryName, balance
from main.country c join
     main.person p
     on c.countryId = p.countryId
where balance = (select MAX(balance)
                 from main.person p2 join
                      main.country c2
                      on c2.countryId = p2.countryId
                 where c.countryId = c2.countryId and p.countryId = p2.countryId
                )
order by countryName;

From what I can tell, you want the highest balance in each country, along with duplicates, if any. You can get these using:

select top (1) with ties c.countryName, p.balance
from main.country c join
     main.person p
     on c.countryId = p.countryId
order by rank() over (partition by c.countryId order by p.balance desc);

To get these in order by country name, you need a subquery:

select cp.*
from (select top (1) with ties c.countryName, p.balance
      from main.country c join
           main.person p
           on c.countryId = p.countryId
      order by rank() over (partition by c.countryId order by p.balance desc)
     ) cp
order by countryName;

1 Comment

@finsters . . . Some wishful programming there. There is no argument; the order is set by the order by.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.