Looping with SQL statements - sql

I am trying to implement a small logic in SQL:
For example : I have two tables A and B
A B
ID Qnt ID Qnt Value
1 50 1 100 1000
2 130 2 200 1000
3 180 3 300 1000
4 320 4 400 2000
5 500 5 500 2000
6 600 2000
7 700 2000
I would to loop through each value of Qnt in TABLE A and check if the value lie between the range of the values in Qnt of TABLE B and get the corresponding value.
I know how I could achieve this with using While loop. But I don't want to do this since looping affects my query performance significantly. I would like to do this with only SQL statements.
Can anyone suggest an idea how I could go with this? just an idea would be great! Any sql would be fine, I would like to know just the logic.
The output would look like :
Output
ID Qnt Value
1 50 1000
2 130 1000
3 180 1000
4 320 2000
5 500 2000
Thanks

This is a lookup. You can do it with a correlated subquery, although the syntax is a bit different in the two databases. Here is the MySQL version:
select a.*,
(select b.value
from b
where b.qnt <= a.qnt
order by b.qnt desc
limit 1
) as value
from a;
Here is the SQL Server version:
select a.*,
(select top 1 b.value
from b
where b.qnt <= a.qnt
order by b.qnt desc
) as value
from a;

Related

SQL query - Impossible to repeat a sum on different lines

I'm new to SQL and I can't solve this problem :
I have 2 tables in input :
The table "ORDER" :
Parcel_num
Order_num
A
1
B
1
C
1
D
2
The table "PARCEL" :
Parcel_num
Weight
A
1000
B
500
C
1500
D
1000
I have to display this tab in output :
Parcel_num
Order_num
Weight/order
A
1
3000
B
1
3000
C
1
3000
D
2
1000
I'm able to get the weight/order using this query :
> SELECT ORDER.Order_num, SUM(PARCEL.Weight) AS SUM_WEIGHT FROM PARCEL
> INNER JOIN ORDER ON PARCEL.Parcel_num=ORDER.Order_num GROUP BY
> ORDER.Order_num
But i'm not able to repeat this sum for each parcel.
I've tried using subqueries but I get errors anyway...
Try this:
SELECT PARCEL.Parcel_num, SUM(PARCEL.Weight) AS SUM_WEIGHT
FROM PARCEL
GROUP BY PARCEL.Parcel_num

Assigning a value of data for each record having the same condition in SQL Server 2008

I have a table in SQL Server 2008 like:
Period Name Value
1 A 10
2 A 20
3 A 30
4 A 40
1 B 50
2 B 80
3 B 70
4 B 60
What I need to write a select query includes a new column MainValue which contains the value where period=4 for a name for each data.
Example:
Period Name Value MainValue
1 A 10 40
2 A 20 40
3 A 30 40
4 A 40 40
1 B 50 60
2 B 80 60
3 B 70 60
4 B 60 60
How can I provide this? I tried the one below, but it is not working as I want.
Select
*,
(select Value where Period = 4) as MainValue
from myTable;
Any help would be appreciated.
Try this:
SELECT Period, Name, Value,
MAX(CASE WHEN Period=4 THEN Value END) OVER (PARTITION BY Name) AS MainValue
FROM mytable
The query uses a window function with a condition applied over Name partitions: the function returns the Value corresponding to Period=4 inside each partition.
You can do this a number of ways. A correlated sub-query as the column, a cross apply to a correlated query, or a cte. I personally like the cte approach. It would look something like this.
with MainValues as
(
select Name
, Value
from SomeTable
where Period = 4
)
select st.*
, mv.Value as MainValue
from SomeTable st
join MainValues mv on st.Name = mv.Name

Inserting a new indicator column to tell if a given row maximizes another column in SQL

I currently have a table in SQL that looks like this
PRODUCT_ID_1 PRODUCT_ID_2 SCORE
1 2 10
1 3 100
1 10 3000
2 10 10
3 35 100
3 2 1001
That is, PRODUCT_ID_1,PRODUCT_ID_2 is a primary key for this table.
What I would like to do is use this table to add in a row to tell whether or not the current row is the one that maximizes SCORE for a value of PRODUCT_ID_1.
In other words, what I would like to get is the following table:
PRODUCT_ID_1 PRODUCT_ID_2 SCORE IS_MAX_SCORE_FOR_ID_1
1 2 10 0
1 3 100 0
1 10 3000 1
2 10 10 1
3 35 100 0
3 2 1001 1
I am wondering how I can compute the IS_MAX_SCORE_FOR_ID_1 column and insert it into the table without having to create a new table.
You can try like this...
Select PRODUCT_ID_1, PRODUCT_ID_2 ,SCORE,
(Case when b.Score=
(Select Max(a.Score) from TableName a where a.PRODUCT_ID_1=b. PRODUCT_ID_1)
then 1 else 0 End) as IS_MAX_SCORE_FOR_ID_1
from TableName b
You can use a window function for this:
select product_id_1,
product_id_2,
score,
case
when score = max(score) over (partition by product_id_1) then 1
else 0
end as is_max_score_for_id_1
from the_table
order by product_id_1;
(The above is ANSI SQL and should run on any modern DBMS)

how to group by and return sum row in Postgres

I am stuck here. I have row in Postgres like this:
id amount
a 5000
a 1500
a 500
b 2000
b 1000
c 4000
How is the sql syntax to get result like this?
id amount
a 7000
b 3000
c 4000
SELECT id, SUM(amount) AS amount
FROM yourtable
GROUP BY id

Simple query in DB2 for AS400

This is a very easy query (I think) but I stil can't do it.
I have some data like this:
A B C
1 1100 5
1 1100 5
1 500 1
2 1200 4
2 1200 4
2 600 1
3 1300 3
3 1300 3
3 700 1
And I want to return the top B per A with the SUM of C, or something like this:
A B C
1 1100 10
2 1200 8
3 1300 6
Also, I'm using DB2 for AS400, so I can't use the TOP keyword.
EDIT # OMG Ponies:
I tried somethine like
SELECT
t.A
,MAX(t.B)
,SUM(t.C)
FROM t
GROUP BY
t.A
But it returns the total sum of C, not only the ones selected:
A B C
1 1100 11
2 1200 9
3 1300 7
Thanks!
Looks like you want the max B value for each A value, so
SELECT t.a,
MAX(t.b)
FROM TABLE t
GROUP BY t.a
If you want entire record associated with the A and MAX(b) values, use:
SELECT t.a,
t.b,
t.c
FROM TABLE t
JOIN (SELECT x.a,
MAX(x.b) AS max_b
FROM TABLE x
GROUP BY x.a) y ON y.a = t.a
AND y.max_b = t.b
On DB2 you can use the FETCH FIRST # ROWS ONLY
to mimic the TOP predicate but it goes at the END of the SQL statement