Select results from the middle of a sorted list? - sql

I've got a simple table with 300 rows, and after ordering them I want to select rows 11-50. Do I limit by 50 and remove the top 10 rows somehow?

SELECT *
FROM table
ORDER BY somecolumn
LIMIT 10,40
From MySQL's manual:
The LIMIT clause can be used to constrain the number of rows returned by the SELECT statement. LIMIT takes one or two numeric arguments, which must both be nonnegative integer constants (except when using prepared statements).
With two arguments, the first argument specifies the offset of the first row to return, and the second specifies the maximum number of rows to return. The offset of the initial row is 0 (not 1)

The LIMIT syntax includes an offset value, so you'd use:
LIMIT 10, 40
...to get rows 11 - 50, because the initial offset row is zero (not 1).

Related

SQLite3 Order by highest/lowest numerical value

I am trying to do a query in SQLite3 to order a column by numerical value. Instead of getting the rows ordered by the numerical value of the column, the rows are ordered alphabetically by the first digit's numerical value.
For example in the query below 110 appears before 2 because the first digit (1) is less than two. However the entire number 110 is greater than 2 and I need that to appear after 2.
sqlite> SELECT digit,text FROM test ORDER BY digit;
1|one
110|One Hundred Ten
2|TWO
3|Three
sqlite>
Is there a way to make 110 appear after 2?
It seems like digit is a stored as a string, not as a number. You need to convert it to a number to get the proper ordering. A simple approach uses:
SELECT digit, text
FROM test
ORDER BY digit + 0

How to calculate the ratio of this column with 2 rows

I am very new to SQL and am having difficulty figuring out hot to divide row1 (101) by row2 (576).
COUNT
101
576
I want the output to be a single value expressed to 2 decimal places.
Any tips?
Thanks for the help
For two rows, it's easy.
If you have a big input table, and you want to divide the first row by the second, the third row by the fourth, etc, then you need an ordering column to save yourself.
So, with a two-row table (remember, tables are never ordered), you just rely on the fact that you divide the smaller number by the bigger number.
Here goes:
WITH
-- your input ...
input(counter) AS ( -- count is reserved word, use another name ...
SELECT 101
UNION ALL SELECT 576
)
-- cheat and just divide the smaller by the bigger
-- as "#Gordon Linoff" suggests
-- force a float division by adding a non-integer operand
-- and hard-cast it to DECIMAL(5,2)
SELECT
CAST(
MIN(counter) * 1.00 / MAX(counter)
AS DECIMAL(5,2)
) AS result
FROM input;
-- out result
-- out ----------
-- out 0.18
If, however, you have many rows, and you always need to divide the first row by the second, the third row by the fourth, that is, each odd row in the order by the next even row in the order, then you need an ordering column.
Is your problem just what you suggested, or is there more to it?
There is no such thing as row "1" or "2" in a table. Tables represent unordered sets, so without a column specifying the ordering, there is no first or second row.
You can use aggregation to divide by min by the max:
select min(count) * 1.0 / max(count)
from t;
Note the * 1.0. Postgres does integer division, so you want to convert to something with a decimal point.

Result if TOP 10 values are not there

SELECT AVG(f.P_PRICE_LOW) as TOP10_Average
FROM (SELECT top 10 P_PRICE_LOW
FROM fp_basic_bd
WHERE fs_perm_sec_id='B00242-S-US'
ORDER BY fs_perm_sec_id
) as f
By using this query I am calculating the average of top 10 price values. My question is:
How the average will be calculated if the subquery returns less than 10 values?
The average is calculated over whatever the inner query returns, with NULL values being ignored by AVG().
If inner query returns 10 non-null values, then result = SUM(10 values) / 10.
If inner query returns 3 non-null values, then result = SUM(3 values) / 3.
If inner query returns no non-null values or even no values at all, then result = NULL.
You can think of TOP as restricting the total number of rows returned, not adding or manipulating any values. So if your query returns 90 rows total, TOP will just return the first N of those, so the first 10 in your case. If there are less than N rows returned, then TOP will return all rows found since it did not exceed the maximum value specified.
For your specific case, if your subquery returned <10 rows, the average value found would be based on those rows instead of 10. Since you are using the AVG function instead of manually finding the average yourself, the value found will still be the correct average of the rows found. So if you have 6 rows returned in the subquery, AVG would do the same as (r1 + r2 + ... + r6)/6.

How do modified condition operators work? SQL - ALL and ANY

Lets say I have a table A with attribute numbers that looks like this.
A
numbers
1
2
3
4
5
6
7
8
9
10
What will this query return? How is the 5 getting compared?
SELECT numbers
FROM A
WHERE 5 > ALL (SELECT numbers FROM a)
The ALL statement requires that ALL of the results returned by your subquery
(SELECT numbers FROM A)
to respect the condition (to be smaller than 5), otherwise the condition is not met and no results are returned.
In your case, there are numbers returned by the subquery, SELECT numbers FROM a, 6, 7, 8, 9, 10 which are greater than 5, thus not ALL numbers respect the condition, so the condition is evaluated to FALSE, and no rows are returned.
Update:
Based on your comments I added details to my answer:
The statement using ALL condition should be read as:
"If ALL of the numbers returned by (SELECT numbers FROM A) are smaller than 5, then return the numbers selected by your MAIN SELECT."
The statement using ANY condition should be read as:
"If ANY of the numbers returned by (SELECT numbers FROM A) are smaller than 5, then return the numbers selected by your MAIN SELECT."
You can run the query in this SQLFiddle to see how the results change, just replace ANY with ALL and see the difference.
It will return an empty resultset (no rows).
The WHERE clause is evaluated for each row in the table A [first instance].
The WHERE clause tests whether 5 is greater than EACH row in table A [second instance].
It is not (there are several rows where the value is greater than 5) so the WHERE clause is always false.
Therefore no rows from table A [first instance] pass the query, therefore no rows are returned.

SQL Server SQL Select: How do I select rows where sum of a column is within a specified multiple?

I have a process that needs to select rows from a Table (queued items) each row has a quantity column and I need to select rows where the quantities add to a specific multiple. The mulitple is the order of between around 4, 8, 10 (but could in theory be any multiple. (odd or even)
Any suggestions on how to select rows where the sum of a field is of a specified multiple?
My first thought would be to use some kind of MOD function which I believe in SQL server is the % sign. So the criteria would be something like this
WHERE MyField % 4 = 0 OR MyField % 8 = 0
It might not be that fast so another way might be to make a temp table containing say 100 values of the X times table (where X is the multiple you are looking for) and join on that