Sqlite query for getting index from sorted result - sql

I need to make a sql query were in I have a table which consists below columns
id Name Color
1 Water red
5 Sun blue Light
7 Fire green
10 Wter red
21 Son blue Light
24 Fore green
So the requirement is I have a record say
5 Sun blue Light
Now I need to get the index of above record from the sorted result of the Name. Say below can be the select query.
SELECT * FROM MYTABLENAME WHERE COLOR LIKE “blue/%” ORDER BY Name ASC
Note:- I cannot load all the records in my memory and iterate as the records can be huge at times. So need to come up with a query that gives the exact indexof the record without loading the records.
Thanks In advance

If you haven't stored the sort result in a temporary table, the only way to do this is to count how many records would be sorted before this record:
SELECT COUNT(*)
FROM MYTABLENAME
WHERE COLOR LIKE “blue/%”
AND Name <= 'Sun'

Related

Is there a way do dynamically set ROWS BETWEEN X PRECENDING AND CURRENT ROW?

i'm looking for a way to, on my query, dynamically set the beginning of the window function on Sql Server using ROWS BETWEEN.
Something like:
SUM(field) OVER(ORDER BY field2 ROWS BETWEEN field3 PRECEDING AND CURRENT ROW)
field3 holds the amount of items (via group by from a CTE) that represent a group.
Is that possible or should i try a different approach?
>> EDIT
My query is too big and messy to share here, but let me try to explain what i need. It's from a report builder which allows users to create custom formulas, like "emplyoees/10". This also allows the user to simply input a formula like "12" and i need to calculate subtotals and the grand total for them. When using a field, like "employees", everything works fine. But for constant values i can't sum the values without rewriting a lot of stuff (which i'm trying to avoid).
So, consider a CTE called "aggregator" and the following query:
SELECT
*,
"employees"/10 as "ten_percent"
12 as "twelve"
FROM aggregator
This query returns this output:
row_type counter company_name department_name employees ten_percent twelve
data 1 A A1 10 1 12
data 1 A A2 15 1,5 12
data 1 A A3 10 1 12
subtotal 3 A 35 3,5 12
data 1 B B1 10 1 12
subtotal 1 B 10 1 12
total 4 45 4,5 12
As you can see, the values fot "twelve" are wrong for subtotal and total row types. I'm trying to solve this without changing the CTE.
ROLLUP won't work because i already have the sum for other columns.
I tried this (i ommited "row_type_sort" on the table above, it defines the sorting):
CASE
WHEN row_type = 'data' THEN
MAX(aggregator.[twelve])
ELSE
SUM(SUM(aggregator.[twelve]))
OVER (ORDER BY "row_type_sort" ROWS BETWEEN unbounded PRECEDING AND CURRENT ROW)
END AS "twelve"
This would work OK if i could change "unbounded" by the value of column "counter", which was my original question.
LAG/LEAD wasn't helpful neither.
I'm out of ideas. Is it possible to achieve what i need only by changing this part of the query, or the result of the CTE should be changed as well?
Thanks

SAP HANA SQL - Concatenate multiple result rows for a single column into a single row

I am pulling data and when I pull in the text field my results for the "distinct ID" are sometimes being duplicated when there are multiple results for that ID. Is there a way to concatenate the results into a single column/row rather than having them duplicated?
It looks like there are ways in other SQL platforms but I have not been able to find something that works in HANA.
Example
Select
Distinct ID
From Table1
If I pull only Distinct ID I get the following:
ID
1
2
3
4
However when I pull the following:
Example
Select
Distinct ID,Text
From Table1
I get something like
ID
Text
1
Dog
2
Cat
2
Dog
3
Fish
4
Bird
4
Horse
I am trying to Concat the Text field when there is more than 1 row for each ID.
What I need the results to be (Having a "break" between results so that they are on separate lines would be even better but at least a "," would work):
ID
Text
1
Dog
2
Cat,Dog
3
Fish
4
Bird,Horse
I see Kiran has just referred to another valid answer in the comment, but in your example this would work.
SELECT ID, STRING_AGG(Text, ',')
FROM TABLE1
GROUP BY ID;
You can replace the ',' with other characters, maybe a '\n' for a line break
I would caution against the approach to concatenate rows in this way, unless you know your data well. There is no effective limit to the rows and length of the string that you will generate, but HANA will have a limit on string length, so consider that.

Sum of distinct items values Oracle SQL

I got data like this:
ITEM COLOR VOL
1 RED 3
2 BLUE 3
3 RED 3
4 GREEN 12
5 BLUE 3
6 GREEN 12
and I want to have the total sum of each color,
mean RED + BLUE + GREEN = 3+3+12 = 18
P.S I can't do it in sub-query since it is a part of a big query already. I am looking for a way could do it in select clause.something like
select sum(distinct(COLOR) VOL) from myTable group by COLOR
Thanks a lot!
Sum the sum of distinct, as grouped by color
select sum(sum(distinct VOL))
from MyTable
group by COLOR
Tested locally and here
One approach uses a CTE or subquery to find the mean volumes for each color. Then take the sum of all mean volumes, for all colors.
WITH cte AS (
SELECT COLOR, AVG(VOL) AS VOL -- or MIN(VOL), or MAX(VOL)
FROM yourTable
GROUP BY COLOR
)
SELECT SUM(t.VOL)
FROM cte t
sum(max(vol)) from ... group by color
will work, but it's not clear why you should need such a thing. Likely this sum can be computed (much) earlier in your query, not right at the end.
Proof of concept (on a standard Oracle schema):
SQL> select sum(max(sal)) from scott.emp group by deptno;
SUM(MAX(SAL))
-------------
10850
1 row selected.

postgreSQL get index of a row that is outside the limit you searched for

I am new to SQL and I am not sure how to properly search my question so I will ask here.
Please see this link to see the SQL tables and queries I am working with
In this example there are 6 rows and I am limiting my search to start at the first index and give me at most 2. However, I would like to know the index of the row that has id 1.
When I use the query I describe in sqlfiddle, It shows me rows with id 5 and 23. But it doesn't include the row with id 1. However, I need to know the index of the row with id 1..
click here to see the full list
The link above prints out all of the rows and we can see that index 3 has the row containing id 1.
However I need to know that index without asking for the entire Array.
Why is this important? Well, lets say that we have 1 million rows. And if I ask for a million rows, that would mean allocating an array of one million. I could parse the array until I find the id I am looking for. However, allocating a million is way too costly.
Lets say for example that the row I am looking for resides in index 26, But I make my query so that it starts at index 0 and limits to 10. The array that I get from this query would not contain index 26. However I still need to know that it IS at index 26.
So this magic query would give me two things:
the top ten rows of the sorted rows
the index of a specified id (e.g. id of 1) regardless of its placement in the list.
Is this a possible query?
Clarification:
I use the word index to mean the row number.
If a we query a list of names from the db, we could get something like this:
bob
frank
dawn
then bob would be at index 0, frank would be at index 1 and dawn at index 2.
If I ORDER BY name ASC then the list of names would become
bob
dawn
frank
bob would be index 0 dawn would be index 1 and frank would be index 2.
I hope this makes things more clear.
If you want the row number, use the row_number() function:
SELECT *
FROM (SELECT ud.id, ud.team_name, ui.name, ui.date_created,
row_number() over (order by ui.name, ui.id) as rownumber
FROM user_data ud JOIN
user_infos ui
ON ui.id = ud.id
WHERE ui.date_created BETWEEN NOW() - INTERVAL '1 year' AND NOW()
) t
WHERE rownumber <= 10 or id = 1;
If you want them in order, just add order by rownumber as the last statement.

Working with sets of rows in (My)SQL and comparing values

I am trying to figure out the SQL for doing some relatively simple operations on sets of records in a table but I am stuck. Consider a table with multiple rows per item, all identified by a common key.
For example:
serial model color
XX1 A blue
XX2 A blue
XX3 A green
XX5 B red
XX6 B blue
XX1 B blue
What I would for example want to do is:
Assuming that all model A rows must have the same color, find the rows which dont. (for example, XX3 is green).
Assuming that a given serial number can only point to a single type of model, find out the rows which that does not occur (for example XX1 points both to A and B)
These are all simple logically things to do. To abstract it, I want to know how to group things by using a single key (or combination of keys) and then compare the values of those records.
Should I use a join on the same table? should i use some sort of array or similar?
thanks for your help
For 1:
SELECT model, color, COUNT(*) AS num FROM yourTable GROUP BY model, color;
This will give you a list of each model and each color for that model along with the count. So the output from your dataset would be:
model color num
A blue 2
A green 1
B red 1
B blue 2
From this output you can easily see what's incorrect and fix it using an UPDATE statement or do a blanket operation where you assign the most popular color to each model.
For 2:
SELECT serial, COUNT(*) AS num FROM yourTable GROUP BY serial HAVING num > 1
The output for this would be:
serial num
XX1 2
To address #1, I would use a self-join (a join on the same table, as you put it).
For example,
select *
from mytable
where serial in (select serial
from mytable
group by model, color
having count(*) = 1)
would find all the serial numbers that only exist in one color. I did not test this, but I hope you see what it does. The inner select finds all the records that only occur once, then the outer select shows all detail for those serials.
Of course, having said that, this is a poor table design. But I don't think that was your question. And I hope this was a made up example for a real situation. My concern would be that there is no reason to assume that the single occurrence is actually bad -- it could be that there are 10 records, all of which have a distinct color. This approach would tell you that all of them are wrong, and you would be unable to decide which was correct.