How to select various items for each Distinct code value - sql-order-by

At the moment, I am doing this process in excel but it is taking a very long time and thought that SQL might offer a more efficient alternative.
The table, projections, is 58k rows and originally comes ordered in a nonsensical way. There are 18 columns but only two have any significance, occ_code and indcode. In excel, I am arranging in ascending by occ_code and then arranging that subset in ascending order by indcode. An example of the intended result is given below.
indcode occ_code
000000 000000
110000 000000
111000 000000
000000 111011
110000 111011
120000 111011
000000 122011
As for SQL, could this be done with the following code.
Select Distinct Occ_code,indcode From dbo.projections
Order by occ_code asc, indcode asc

Your code will work:
Select Distinct Occ_code,indcode From dbo.projections Order by occ_code asc, indcode asc
An alternative would be to use group by which would allow you to use aggregation functions:
Select Occ_code, indcode From dbo.projections group by Occ_code, indcode Order by occ_code asc, indcode asc
Here you could use count(*) with it to find those combined codes with no duplicates:
Select Occ_code, indcode, count(*) From dbo.projections group by Occ_code, indcode having count(*) = 1 Order by occ_code asc, indcode asc

You must also include indcode in your select if you want it in the results. the query as you wrote it would only give one row per distinct occ_code value.

Related

Trying to display top 3 amount from a table using sql query in oracle 11g..column is of varchar type

Am trying to list top 3 records from atable based on some amount stored in a column FTE_TMUSD which is of varchar datatype
below is the query i tried
SELECT *FROM
(
SELECT * FROM FSE_TM_ENTRY
ORDER BY FTE_TMUSD desc
)
WHERE rownum <= 3
ORDER BY FTE_TMUSD DESC ;
o/p i got
972,9680,963 -->FTE_TMUSD values which are not displayed in desc
I am expecting an o/p which will display the top 3 records of values
That should work; inline view is ordered by FTE_TMUSD in descending order, and you're selecting values from it.
What looks suspicious are values you specified as the result. It appears that FTE_TMUSD's datatype is VARCHAR2 (ah, yes - it is, you said so). It means that values are sorted as strings, not numbers - and it seems that you expect numbers. So, apply TO_NUMBER to that column. Note that it'll fail if column contains anything but numbers (for example, if there's a value 972C).
Also, an alternative to your query might be use of analytic functions, such as row_number:
with temp as
(select f.*,
row_number() over (order by to_number(f.fte_tmusd) desc) rn
from fse_tm_entry f
)
select *
from temp
where rn <= 3;

Trying to figure out top 5 land areas of the 50 states in the U.S

I have a table created. With one column named states and another column called land area. I am using oracle 11g. I have looked at various questions on here and cannot find a solution. Here is what I have tried so far:
SELECT LandAreas, State
FROM ( SELECT LandAreas, State, DENSE_RANK() OVER (ORDER BY State DESC) sal_dense_rank
FROM Map )
WHERE sal_dense_rank >= 5;
This does not provide the top 5 land areas as far as number wise.
I have also tried this one but no go either:
SELECT * FROM Map order by State desc)
where rownum < 5;
Anyone have any suggestions to get me on the right track??
Here is a samle of the table
states land areas
michagan 15000
florida 25000
tennessee 10000
alabama 80000
new york 150000
california 20000
oregon 5000
texas 6000
utah 3000
nebraska 1000
Desired output from query:
States land area
new york 150000
alabama 80000
florida 25000
california 20000
Try:
Select * from
(SELECT State, LandAreas FROM Map ORDER BY LandAreas DESC)
where rownum < 6
Link to Fiddle
Use a HAVING clause and count the number state states larger:
SELECT m.state, m.landArea
FROM Map m
LEFT JOIN Map m2 on m2.landArea > m.landArea
GROUP BY m.state, m.landArea
HAVING count(*) < 5
ORDER BY m.landArea DESC
See SQLFiddle
This joins each state to every state whose area is greater, then uses a HAVING clause to return only those states where the number of larger states was less than 5.
Ties are all returned, leading to more than 5 rows in the case of a tie for 5th.
The left join is needed for the case of the largest state, which has no other larger state to join to.
The ORDER BY is optional.
Try something like this
select m.states,m.landarea
from map m
where (select count(‘x’) from map m2 where m2.landarea > m.landarea)<=5
order by m.landarea
There are two bloomers in your posted code.
You need to use landarea in the DENSE_RANK() call. At the moment you're ordering the states in reverse alphabetical order.
Your filter in the outer query is the wrong way around: you're excluding the top four results.
Here is what you need ...
SELECT LandArea, State
FROM ( SELECT LandArea
, State
, DENSE_RANK() OVER (ORDER BY landarea DESC) as area_dr
FROM Maps )
WHERE area_dr <= 5
order by area_dr;
... and here is the SQL Fiddle to prove it. (I'm going with the statement in the question that you want the top 5 biggest states and ignoring the fact that your desired result set has only four rows. But adjust the outer filter as you will).
There are three different functions for deriving top-N result sets: DENSE_RANK, RANK and ROW_NUMBER.
Using ROW_NUMBER will always guarantee you 5 rows in the result set, but you may get the wrong result if there are several states with the same land area (unlikely in this case, but other data sets will produce such clashes). So: 1,2,3,4,5
The difference between RANK and DENSE_RANK is how they handle ties. DENSE_RANK always produces a series of consecutive numbers, regardless of how many rows there are in each rank. So: 1,2,2,3,3,3,4,5
RANK on the other hand will produce a sparse series if a given rank has more than one hit. So: 1,2,2,4,4,4.
Note that each of the example result sets has a different number of rows. Which one is correct? It depends on the precise question you want to ask.
Using a sorted sub-query with the ROWNUM pseudo-column will work like the ROW_NUMBER function, but I prefer using ROW_NUMBER because it is more powerful and more error-proof.

Can I lua sort a table that has a column created by "row_number()" function in postgresql?

I have a select statement that includes a call to the row_number() function, which technically gives me a unique id per row that is returned.
SELECT f.*, row_number() as row_id OVER(ORDER BY f.name)
FROM widgets f
It'd be kinda cool if i could somehow use this row_id to sort the table. I'd now like to try to use the row_number to sort like so:
table.sort(mytable, function(a,b) return a.row_id< b.row_id end)
I'm just trying to save myself from having to loop through the results to add a unique id and then sort it but maybe it's not possible.
I don't know how you would express this in Lua, but in Postgres you can order by a column alias. The Postgres query would be:
SELECT f.*, row_number() OVER (ORDER BY f.name) as row_id
FROM widgets f
ORDER BY row_id;
The fact that you don't want to order by f.name suggests that you have duplicates. Do note that ordering in SQL is not guaranteed to be stable. That is, duplicate names could be in different orders. If you have a way of making the ordering stable (i.e. by uniquely identifying each row), you can use those columns in the order by.

MDX rather complicated sorting

I can't find out a way, how to sort my query, this is the simple query:
SELECT {[Measures].[IB]}
ON COLUMNS,
{[Dim_Product_Models_new].[PLA].members } *
{[Dim Dates_new].[Date Full].&[2013-02-01]:[Dim Dates_new].[Date Full].&[2014-01-01]}
ON ROWS
FROM [cub_dashboard_spares]
The think is, I would get a result for 6 PLAs combined across 12 months (72 rows in total), however it is sorted alphabetically upon PLA.
What i need, is to sort the PLAs based on a measure in last month (2014-01-01 in this case).
Is there any way to perform this task so that the groupping (PLAs, Dates from 2013-02 to 2013-12) is perserved, but only the order of my PLAs is different. (PLA with highest measure in last month would be first, and so on)
Thank you very much for any kind of help
Just put the sorted set on the rows, using the Order function. The third parameter of this function is DESC if you want to sort within each hierarchy level, but still want to get parents before children (like ALL before the single attribute members), or BDESC if you want to sort across all levels.
SELECT {[Measures].[IB]}
ON COLUMNS,
Order({[Dim_Product_Models_new].[PLA].members },
([Measures].[IB], [Dim Dates_new].[Date Full].&[2014-01-01]),
DESC)
*
{[Dim Dates_new].[Date Full].&[2013-02-01]:[Dim Dates_new].[Date Full].&[2014-01-01]}
ON ROWS
FROM [cub_dashboard_spares]
The order function over a crossjoin should preserve the initial order of the first set so reversing the order of the tuple will do the job:
SELECT
{
[Measures].[IB]
} ON COLUMNS,
order(
{[Dim Dates_new].[Date Full].&[2013-02-01]:[Dim Dates_new].[Date Full].&[2014-01-01]} *
{[Dim_Product_Models_new].[PLA].members } ,
[Measures].[IB],
desc
) ON ROWS
FROM [cub_dashboard_spares]
If you want to preserve the oder of appearance of the column labels, you can use the generate function like in the following example from the AW cube:
SELECT
{[Measures].[Internet Sales Amount]} ON 0
,Generate
(
{[Customer].[Country].&[Australia]:[Customer].[Country].&[United Kingdom]}
,(
Order
(
[Date].[Calendar Year].[Calendar Year].MEMBERS
,(
[Customer].[Country].CurrentMember
,[Measures].[Internet Sales Amount]
)
,DESC
)
,[Customer].[Country].CurrentMember
)
) ON 1
FROM [Adventure Works];
Philip,

Trying to select all records where two fields are distinct (but the rest don't have to be)

I have a table that has 14 columns in it. These columns are color, type, ft, date, count, etc. What I need is to select all distinct records of id and type with the most recent date. So, for example...
color------type-----------date
red--------work-----------01/01/01
red---------play----------02/02/02
red---------play----------03/03/03
In this case, I want to return red, work, 01/01/01 and red, play 03/03/03. Hopefully this makes sense. I've tried different combinations of select unique and select distinct and group bys, and I haven't been able to come up with anything.
Here is the SQL statement I'm trying:
select distinct
chock_id,
roll_type,
max(chock_service_dt),
chock_id_dt,
chock_seq_num,
chock_service_cmnt,
total_rolled_lineal_ft,
total_rolled_tons,
chock_usage_cnt,
chock_insert_dt,
record_modify_dt,
next_chock_service_dt_act,
previous_alarm_value,
upload_complete_yn
from
tp07_chock_summary_row
group by
chock_id,
roll_type,
chock_service_dt,
chock_id_dt,
chock_seq_num,
chock_service_cmnt,
total_rolled_lineal_ft,
total_rolled_tons,
chock_usage_cnt,
chock_insert_dt,
record_modify_dt,
next_chock_service_dt_act,
previous_alarm_value,
upload_complete_yn;
Here's a screenshot. Like I said in a comment below, like in rows 2 and 4, I can't have multiple records with the same chock_id and roll_type.
Given your new requirements, which you did not explain initially, this should do it:
select
chock_id,
roll_type,
chock_service_dt,
chock_id_dt,
chock_seq_num,
chock_service_cmnt,
total_rolled_lineal_ft,
total_rolled_tons,
chock_usage_cnt,
chock_insert_dt,
record_modify_dt,
next_chock_service_dt_act,
previous_alarm_value,
upload_complete_yn
from (
select
chock_id,
roll_type,
chock_service_dt,
chock_id_dt,
chock_seq_num,
chock_service_cmnt,
total_rolled_lineal_ft,
total_rolled_tons,
chock_usage_cnt,
chock_insert_dt,
record_modify_dt,
next_chock_service_dt_act,
previous_alarm_value,
upload_complete_yn,
row_number() over (
partition by chock_id, roll_type
order by chock_service_dt desc
) rn
from
tp07_chock_summary_row
) where rn = 1
select color, type, max(date)
from ...
group by color, type
select
color,
type,
max(date)
from
yourtable
group by
color,
type

Resources