Closest value (MS Access) - sql

Is it possible to get closest(smaller) value of the same id in MS Access database?
It only need one expression, but I don't know how to write it properly.
Should looks like this:
ID Value Value2
1 10 0
2 5 0
1 20 10
1 50 20
2 15 5
...and so on..........
I have tried to use Dlookup and Max functions but I failed.
Thank you for any help.

You seem to want the previous value. There is no way to do this unless you have a column specifying the ordering. If so:
select t.*,
(select top (1) t2.value
from t as t2
where t2.? < t.?
order by t2.? desc
) as prev_value
from t;
The ? is for the column that specifies the ordering.

Related

How can I create this conditional grouped field on SQL Server 2008?

Sorry for this question, but i cannot resolve this simple query.
I have this table:
ID_Type Item
-----------------
A 1
P 2
P 3
A 4
P 5
A 6
I need to calculate a "group" incremental counter based on ID_Type Field where This field has an "A" Value. This is the expected result:
ID_Type Item Counter
-----------------------------
A 1 1
P 2 1
P 3 1
A 4 2
P 5 2
A 6 3
So every time a record with ID_Type='A' appear, I need to increment the counter. Any help will be apreciated.
In SQL Server 2012+, you can use a cumulative sum:
select t.*,
sum(case when id_type = 'A' then 1 else 0 end) over (order by item) as counter
from t;
This will be much more efficient than a correlated subquery approach, particularly on larger data sets.
One way is a subquery:
SELECT ID_Type, Item, (
SELECT COUNT(*) FROM MyTable t2
WHERE t2.Item <= t1.Item
AND t2.ID_Type='A'
) AS Counter
FROM MyTable t1
ORDER BY Item ASC
This will work on any version of SQL Server.

Group Numerical Data Within Specific Ranges

I want to group the data from one of the tables in a SQL database. The field to be used for grouping is numerical and the groups I want do not follow any mathematical formula e.g.
Group 0 value unknown (NULL)
Group 1 values 0 - 499
Group 2 value 500 - 999
Group 3 value 1000 - 1999
Group 4 value 2000 - 4999
Group 5 value 5000 +
How can I achieve this with TSQL?
By the way I want to do this to display in a Crystal Report, so if there is a better way of doing this in Crystal Reports rather than through the SQL Select statement then please advise.
You can use a case to create a custom group. If you define the case in a subquery, you don't have to repeat the definition:
select Grp
, sum(col2)
, avg(col3)
from (
select case
when col1 is null then 0
when col1 between 0 and 499 then 1
when col1 between 500 and 999 then 2
...
end as Grp
, *
) as SubQueryAlias
group by
Grp

Is there a way to sum the rows above the current row

I am trying to replicate a spreadsheet into a database and I am stumped on how to only sum the rows above the current row like I can do in excel. For example, the formula for the one column is as follows:
=SUM($B$9:$B9)/SUM($E$9:$E9)
=SUM($B$9:$B10)/SUM($E$9:$E10)
=SUM($B$9:$B11)/SUM($E$9:$E11)
.... and so on.
I need to somehow reproduce this formula in my select qry but not sure how?
SELECT Column1,Column2, SUM(Column1) + SUM(Column2) as Expr1
From tblTest
Group By Column1,Column2
Any ideas?
Col1 Col2 Col3 Total Col1/Total Trying to get this
7 0 3 10 70.00% 70.00%
1 0 1 100.00% 72.73%
2 0 4 6 33.33% 58.82%
3 1 1 5 60.00% 59.09%
The trick is you want to use a subquery with a way to identify all the previous rows.
SELECT ID,
(
SELECT SUM(ValueColumn)
FROM Test T2
WHERE T2.ID <= T1.ID
) RunningSum
FROM
Test T1
ORDER BY
T1.ID
This will work. If you have a large data set you may want to just select the data and calculate in your application as you'll be able to keep a running-sum as you loop through the data more efficiently than this query will run.

Add Column values in sql server query

I have result of two queries like:
Result of query 1
ID Value
1 4
2 0
3 6
4 9
Result of query 2
ID Value
1 6
2 4
3 0
4 1
I want to add values column "Value" and show final result:
Result of Both queries
ID Value
1 10
2 4
3 6
4 10
plz guide me...
select id, sum(value) as value
from (
select id, value from query1
uninon all
select id, value from query2
) x
group by id
Try using a JOIN:
SELECT
T1.ID,
T1.Value + T2.Value AS Value
FROM (...query1...) AS T1
JOIN (...query2...) AS T2
ON T1.Id = T2.Id
You may also need to consider what should happen if there is an Id present in one result but not in the other. The current query will omit it from the results. You may want to investigate OUTER JOIN as an alternative.
A not particularly nice but fairly easy to comprehend way would be:
SELECT ID,SUM(Value) FROM
(
(SELECT IDColumn AS ID,ValueColumn AS Value FROM TableA) t1
OUTER JOIN
(SELECT IDColumn AS ID,ValueColumn AS Value FROM TableB) t2
) a GROUP BY a.ID
It has the benefits of
a) I don't know your actual table structure so you should be able to work out how to get the two 'SELECT's working from your original queries
b) If ID doesn't appear in either table, that's fine

Grouping by intervals

Given a table (mytable) containing a numeric field (mynum), how would one go about writing an SQL query which summarizes the table's data based on ranges of values in that field rather than each distinct value?
For the sake of a more concrete example, let's make it intervals of 3 and just "summarize" with a count(*), such that the results tell the number of rows where mynum is 0-2.99, the number of rows where it's 3-5.99, where it's 6-8.99, etc.
The idea is to compute some function of the field that has constant value within each group you want:
select count(*), round(mynum/3.0) foo from mytable group by foo;
I do not know if this is applicable to mySql, anyway in SQL Server I think you can "simply" use group by in both the select list AND the group by list.
Something like:
select
CASE
WHEN id <= 20 THEN 'lessthan20'
WHEN id > 20 and id <= 30 THEN '20and30' ELSE 'morethan30' END,
count(*)
from Profiles
where 1=1
group by
CASE
WHEN id <= 20 THEN 'lessthan20'
WHEN id > 20 and id <= 30 THEN '20and30' ELSE 'morethan30' END
returns something like
column1 column2
---------- ----------
20and30 3
lessthan20 3
morethan30 13