1

This is my SQL View - lets call it MyView :

ECode   SHCode  TotalNrShare    CountryCode Country
000001  +00010  100 UKI United Kingdom
000001  ABENSO  900 USA United States
000355  +00012  1000    ESP Spain
000355  000010  50  FRA France
000042  009999  10  GER Germany
000042  +00012  999 ESP Spain
000787  ABENSO  500 USA United States
000787  000150  500 ITA Italy
001010  009999  100 GER Germany

I would like to return the single row with the highest number in the column TotalNrShare for each ECode.

For example, I’d like to return these results from the above view:

ECode   SHCode  TotalNrShare    CountryCode Country
000001  ABENSO  900 USA United States
000355  +00012  1000    ESP Spain
000042  +00012  999 ESP Spain
000787  ABENSO  500 USA United States
001010  009999  100 GER Germany

(note in the case of ECode 000787 where there are two SHCode's with 500 each, as they are the same amount we can just return the first row rather than both, it isnt important for me which row is returned since this will happen very rarely and my analysis doesnt need to be 100%)

Ive tried various things but do not seem to be able to return either unqiue results or the additional country code/country info that I need.

This is one of my attempts (based on other solutions on this site, but I am doing something wrong):

SELECT tsh.ECode, tsh.SHCode, tsh.TotalNrShare, tsh.CountryCode, tsh.Country
FROM  dbo.MyView AS tsh INNER JOIN
                   (SELECT DISTINCT ECode, MAX(TotalNrShare) AS MaxTotalSH
                    FROM   dbo.MyView
                    GROUP BY ECode) AS groupedtsh ON tsh.ECode = groupedtsh.ECode AND tsh.TotalNrShare = groupedtsh.MaxTotalSH
MatBailie
  • 83,401
  • 18
  • 103
  • 137
NSP
  • 13
  • 1
  • 6
  • 2
    Which flavour of SQL? MySQL, SQL Server, SQLite, Oracle, etc, all have different capabilities and different syntax. Also, what is wrong with your attempted sql query? Did you get error messages, or 'faulty' results? If so, please show these errors or faulty results. – MatBailie Aug 14 '12 at 11:21
  • If any gurus out there can help me I'd really appreciate it! – NSP Aug 14 '12 at 11:22
  • Sorry think some of my text got cut off, its SQL Server 2005 – NSP Aug 14 '12 at 11:23

2 Answers2

2
WITH
  sequenced_data AS
(
  SELECT
    *,
    ROW_NUMBER() OVER (PARTITION BY ECode ORDER BY TotalNrShare) AS sequence_id
  FROM
    myView
)
SELECT
  *
FROM
  sequenced_data
WHERE
  sequence_id = 1

This should, however, give the same results as your example query. It's simply a different approach to accomplish the same thing.

As you say that something is wrong, however, please could you elaborate on what is going wrong? Is TotalNrShare actually a string for example? And is that messing up your ordering (and so the MAX())?

EDIT:

Even if the above code was not compatible with your SQL Server, it shouldn't crash it out completely. You should just get an error message. Try executing Select * By Magic, for example, and it should just give an error. I strongly suggest getting your installation of Management Studio looked at and/or re-installed.

In terms of an alternative, you could do this...

SELECT
  *
FROM
  (SELECT ECode FROM MyView GROUP BY ECode) AS base
CROSS APPLY
  (SELECT TOP 1 * FROM MyView WHERE ECode = base.ECode ORDER BY TotalNrShare DESC) AS data

Ideally you would replace the base sub-query with a table that already has a distinct list of all the ECodes that you are interested in.

MatBailie
  • 83,401
  • 18
  • 103
  • 137
  • Thank you Dems, I tried but it crashes everytime I save your code to my view. Is it for SQL 2005? (as in SQL Management Studio crashes out) – NSP Aug 14 '12 at 11:33
  • In answer to your other query about what my attempt is not doing, it isnt returning a single instance of the ECode. I get multiple rows where I only want the row with the highest TotalNrShares per ECode. I hope that I have made sense.. – NSP Aug 14 '12 at 11:35
  • @NSP - Yes, it is for SQL 2005 and upwards. If it crashes, please include the error message and I will have a look for you. *(Note: If there are any statements before the `WITH` then they **must** be terminated with a `;`. For this reason many people often put `;` before the `WITH` every time, just in case.)* – MatBailie Aug 14 '12 at 11:37
  • Thnx Dems, I am trying to replace my query with your example above, when I apply this to my existing view, the program crashes, no errors, every time. – NSP Aug 14 '12 at 11:42
  • @NSP - are you saying the SQL Server Management Studio crashes every time you run this query? If so, I strongly recommend re-installing it. And if it continues to crash consult your IT Support and/or your DBA team. – MatBailie Aug 14 '12 at 11:46
  • Hi Dems, yes thats right, it crashes out. I dont usually have any other problem with it, just when I apply your code to my view. Not sure whats up in this case. Is there any other way that you can think of? – NSP Aug 14 '12 at 11:49
  • I found this, seems like a bug in SQL Mgt Studio 2005 after SP3 when using ROW_NUMBER() function : http://social.msdn.microsoft.com/Forums/en/sqltools/thread/1558007b-cea1-42b9-a644-dc4475a3b056 – NSP Aug 14 '12 at 11:55
  • @NSP - That should not happen, no matter what SQL you ask Management Studio to execute. Turn your PC off and back on. Re-install Management Studio. This symptom has nothing to do with the SQL Code. That said, I've added an alternative query to my answer. I still recommend the first version, but this should give the same results. – MatBailie Aug 14 '12 at 11:55
  • 1
    @NSP The visual query designer only supports very simple queries just run it in a new query window under a `CREATE VIEW ...` header if you are trying to create a new view with this definition. – Martin Smith Aug 14 '12 at 11:57
  • I think we cross posted, I posted the link to same issue as mine, seems to be a bug after SP3. I will try your other example nxt. thanks so much for your time. – NSP Aug 14 '12 at 11:59
  • @NSP - Sorry, I didn't realise you were using the visual designer, I just assumed you were in a query window - I shouldn't assume! As Martin Smith mention's this does have limitations when you come to more complex queries. Instead you need to use the `New Query` window, you've reached a level of complexity beyond the visual deigner's capability. – MatBailie Aug 14 '12 at 12:05
  • @Dems I have now created that view with the code you advised, it seems good. I will double check the data. – NSP Aug 15 '12 at 07:17
  • @MartinSmith thanks for your suggestion to use the query, I'm quite new to all this and perhaps I take the simplest route! – NSP Aug 15 '12 at 07:19
  • @Dems I tried your code thanks, but Im not returning the row with the highest value in the column TotalNrShares. I spot checked and found one where there were two rows for one ECode, and it returned the row with the lowest value in TotalNrShares. – NSP Aug 15 '12 at 10:08
  • @Dems your second code example (using CROSS APPLY) will not work because of this message "Column names in each view or function must be unique. Column name 'ECode' in view or function 'myView' is specified more than once" - have I done something wrong? – NSP Aug 15 '12 at 10:14
  • @Dems I modified only slightly what you wrote and added DESC to the sort order and it now appears to be OK "ROW_NUMBER() OVER (PARTITION BY ECode ORDER BY TotalNrShare DESC" , thanks for helping me, now I will stop hiding from my boss and get on with the report :) – NSP Aug 15 '12 at 11:05
  • @NSP - in the `CROSS APPLY` version, change the `*` to the list of fields you need. Also, try things without CREATE VIEW to begin with, while you're testing ideas and developing your code; it's often easier to debug. – MatBailie Aug 15 '12 at 12:36
0

try this;

with cte as( 
 SELECT tsh.ECode, tsh.SHCode, tsh.TotalNrShare, tsh.CountryCode, tsh.Country,
 ROW_NUMBER() over (partition by ECode order by SHCode ) as row_num 
FROM  dbo.MyView)
select * from cte where row_num=1
Joe G Joseph
  • 23,518
  • 5
  • 56
  • 58
  • thank you Joe G Joseph, I also tried your code. Again SQL Management Studio (2005) crashed when I attempted to save your example on my view. Im not sure if I am doing something wrong or if its not compatible? – NSP Aug 14 '12 at 11:38
  • I tried your code thanks, but Im not returning the row with the highest value in the column TotalNrShares. I spot checked and found one where there were two rows for one ECode, and it returned the row with the lowest value in TotalNrShares. – NSP Aug 15 '12 at 10:08