Get only the code and total number Oracle SQL - sql

I have 2 tables below.I want to join them
Table1
--------------
T1_id | desc
--------------
1 | test 1
2 | test 2
table2 (detail)
---------------
T2_id | Price
----------------
1 | 100000
1 | 0
1 | 0
2 | 300000
2 | 0
2 | 0
2 | 0
i want the results for this
--------------
code | total
--------------
1 | 100000
2 | 300000
this query
select a.T1_id as Code,
b.price as Total
from Table1 a
inner join table2 b on b.T2_id = a.T1_id
group by a.T1_id ,b.price;

Use below query instead to get the total price
select a.T1_id as Code,
SUM(b.price) as Total
from Table1 a
inner join table2 b on b.T2_id = a.T1_id group by a.T1_id;
Sample output:

Referring to the sample
To exclude 0 values:
SELECT T1_ID AS CODE, PRICE AS PRICE FROM TABLE1 JOIN TABLE2 ON T1_ID=T2_ID
WHERE PRICE<>0
sum of same id:
SELECT T1_ID AS CODE, SUM(PRICE) AS PRICE FROM TABLE1 JOIN TABLE2 ON T1_ID=T2_ID
GROUP BY T1_ID

I fail to see where Table 1 comes into play at all. Presumably the t2_id is a FK back to t1_id. You aren't presenting the column DESC at all, so why are you bothering to join on table_1?
So what's wrong with simply
select t2_id CODE,
sum(price) TOTAL
from table2
group by t2_id
order by t2_id
;

Related

How to do an outer join with full result between two tables

I have two tables:
TABLE1
id_attr
-------
1
2
3
TABLE2
id | id_attr | val
----------------------
10 | 1 | A
10 | 2 | B
As a result I want a table that show:
RESULT
id | id_attr | val
----------------------
10 | 1 | A
10 | 2 | B
10 | 3 | NULL
So I want the row with id=10 and id_attr=3 also when id_Attr=3 is missing in TABLE2 (and I know that because I have a NULL value (or something else) in the val column of RESULT.
NB: I could have others ids in table2. For example, after insert this row on table2: {11,1,A}, as RESULT I want:
id | id_attr | val
----------------------
10 | 1 | A
10 | 2 | B
10 | 3 | NULL
11 | 1 | A
11 | 2 | NULL
11 | 3 | NULL
So, for every id, I want always the match with all id_attr.
Your specific example only has one id, so you can use the following:
select t2.id, t2.id_attr, t2.val
from table2 t2
union all
select 10, t1.id_attr, NULL
from table1 t1
where not exists (select 1 from table2 t2 where t2.id_attr = t1.id_attr);
EDIT:
You can get all combinations of attributes and ids in the following way. Use a cross join to create all the rows you want and then a left join to bring in the data you want:
select i.id, t1.id_attr, t2.val
from (select distinct id from table2) i cross join
table1 t1 left join
table2 t2
on t2.id = i.id and t2.id_attr = t1.id_attr;
It sounds like you want to do just an outer join on id_attr instead of id.
select * from table2 t2
left outer join table1 t1 on t2.id_attr = t1.id_attr;

Postgresql COALESCE does not set default value

I have two tables:
tcars
id | name | car_price
----|---------------------|------------
1 |First_car_name | 1000
2 |Second_car_name | 1200
tcar_optionals
id | id_car | spec | opt_included |price
----|----------|------|-------------------------
1 | 2 |Spec1 | true | 500
2 | 2 |Spec2 | true | 100
3 | 2 |Spec3 | false | 500
4 | 2 |Spec4 | true | 0
5 | 1 |Spec5 | false | 500
6 | 1 |Spec6 | true | 0
And the following query:
select t1.id, coalesce(t1.car_price, 0)+ coalesce(sum(t2.price), 0) as total_price
from tcars t1
left join tcar_optionals t2 on t2.id_car = t1.id
where t2.opt_included and t2.price>0 and t1.id=?
group by t1.id, t1.car_price
It returns the id from tcars and the total_price(car_price+price of included optionals that have price>0).
Example:
for t1.id=2 returns:
id | total_price
----|------------
2 | 1800
The problem appears when I have no included optionals with price>0, for example t1.id = 1.
What it returns:
id | total_price
----|------------
What I need is return only t1.car_price as total_price if there are no included optionals with price>0:
id | total_price
----|------------
1 | 1000
Can someone help me with this problem, please?
You should firstly join the tables with all conditions on the second table and aggregate values from this (joined) result, e.g:
select id, coalesce(car_price, 0)+ coalesce(sum(price), 0) total_price
from tcars
left join tcar_optionals on id = id_car and spec_included
-- where id = 1
group by id, car_price
The condition q1.id_car=1 in the where clause effectively turns your outer join into an inner join because for rows not matching the join condition q1.id_car will be null and the comparison =1 will remove those rows again.
You would need to put that into the JOIN condition - but as you already have a condition on the id_car in the derived table ("q1"), you don't need it anyway.
The other possibility would be to filter on the corresponding value from the tcars table: where t1.id = 1
Edit
By moving the conditions on the t2 table to the join condition you do get what you want:
select t1.id, coalesce(t1.car_price, 0) + coalesce(sum(t2.price), 0) as total_price
from tcars t1
left join tcar_optionals t2
on t2.id_car = t1.id
and t2.opt_included and t2.price > 0 --<< conditions for tcar_optionals go here
where t1.id = 1 --<< limit the car you want to see
group by t1.id;
If id is defined as the primary key in tcars, then group by t1.id is enough.
See the example here: http://rextester.com/YOYF30261
select (t1.car_price + coalesce(extra_price, 0)) as start_price
from tcars t1
left join (select id_car,sum(price) as extra_price from tcar_optionals
where opt_included and price > 0 group by 1) q1 on q1.id_car = t1.id
where t1.id=$1

Creating sql view where the select is dependent on the value of two columns

I want to create a view in my database, based on these three tables:
I would like to select the rows in table3 that has the highest value in Weight, for rows that has the same value in Count.
Then I want them grouped by Category_ID and ordered by Date, so that if two rows in table3 are identical, I want the newest.
Let me give you an example:
Table1
ID | Date | UserId
1 | 2015-01-01 | 1
2 | 2015-01-02 | 1
Table2
ID | table1_ID | Category_ID
1 | 1 | 1
2 | 2 | 1
Table3
ID | table2_ID | Count | Weight
1 | 1 | 5 | 10
2 | 1 | 5 | 20 <-- count is 5 and weight is highest
3 | 1 | 3 | 40
4 | 2 | 5 | 10
5 | 2 | 3 | 40 <-- newest of the two equal rows
Then the result should be row 2 and 5 from table 3.
PS I'm doing this in mssql.
PPS I'm sory if the title is not appropriate, but I did not know how to formulate a good one.
SELECT
*
FROM
(
SELECT
t3.*
,RANK() OVER (PARTITION BY [Count] ORDER BY [Weight] DESC, Date DESC) highest
FROM TABLE3 t3
INNER JOIN TABLE2 t2 ON t2.Id = t3.Table2_Id
INNER JOIN TABLE1 t1 ON t1.Id = t2.Table1_Id
) t
WHERE t.Highest = 1
This will group by the Count (which must be the same). Then it will determine which has the highest weight. If two of more of them have the same 'heighest' weight, it takes the one with the most recent date first.
You can use RANK() analytic function here, and give those rows a rank and than choose the first rank for each ID
Something like
select *
from
(select
ID, table2_ID, Count, Weight,
RANK() OVER (PARTITION BY ID ORDER BY Count, Weight DESC) as Highest
from table3)
where Highest = 1;
This is the syntax for Oracle, if you not using it look in the internet for the your syntax which should be almost the same

Getting all the current effective records from a ORACLE table

I have two tables in oracle database
Table 1 say table1 with fields (id, name)
Records e.g.
###############
id | name
1 | Chair
2 | Table
3 | Bed
###############
and Table 2 say table2 with fields (id, table1_id, date, price)
##############################
id |table1_id| date | price
1 | 1 | 2013-09-09 | 500
2 | 1 | 2013-08-09 | 300
3 | 2 | 2013-09-09 | 5100
4 | 2 | 2013-08-09 | 5000
5 | 3 | 2013-09-09 | 10500
################################
What I want to achieve is to retrieve all the latest price of items from table 2
Result of SQL should be like
##############################
id |table1_id| date | price
1 | 1 | 2013-09-09 | 500
3 | 2 | 2013-09-09 | 5100
5 | 3 | 2013-09-09 | 10500
################################
I am able to run in mysql by following query
SELECT t2.id, t1.id, t1.name, t2.date, t2.price
FROM table1 t1 JOIN table2 t2
ON (t1.id = t2.table1_id
AND t2.id = (
SELECT id
FROM table2
WHERE table1_id = t1.id
ORDER BY table2.date DESC
LIMIT 1
));
but it's not working in ORACLE, Here i Need a query which can run on both server with minor modification
You may try this (shoud work in both MySQL and Oracle):
select t2.id, t2.table1_id, t2.dat, t2.price
from table1 t1 join table2 t2 on (t1.id = t2.table1_id)
join (select table1_id, max(dat) max_date
from table2 group by table1_id) tmax
on (tmax.table1_id = t2.table1_id and tmax.max_date = t2.dat);
This query may return several rows for the same table1_id and date if there are several prices in table2, like this:
##############################
id |table1_id| date | price
1 | 1 | 2013-09-09 | 500
2 | 1 | 2013-09-09 | 300
It's possible to change the query to retrieve only 1 row for each table1_id, but there should be some additional requirements (which row to choose in the above example)
if it doesn't matter then you may try this:
select max(t2.id) as id, t2.table1_id, t2.dat, max(t2.price) as price
from table1 t1 join table2 t2 on (t1.id = t2.table1_id)
join (select table1_id, max(dat) max_date
from table2 group by table1_id) tmax
on (tmax.table1_id = t2.table1_id and tmax.max_date = t2.dat)
group by t2.table1_id, t2.dat;
You can try this using GROUP BY instead, since you're not retrieving the product name from table1 except the product id (which is already in table2)
SELECT id,table1_id,max(date),price
FROM table2
GROUP BY id,table1_id,price
this is what you want :
select t2.id,t2.table1_id,t1.name,t2.pricedate,t2.price
from table1 t1
join
(
select id,table1_id, pricedate,price, row_number() over (partition by table1_id order by pricedate desc) rn
from table2
) t2
on t1.id = t2.table1_id
where t2.rn = 1

Selection with join and sum from table in SQL Server

Id Item
--------------
1 ItemA
2 ItemB
3 ItemC
itemid Price
----------------
1 4
1 3
1 9
2 2
2 4
2 3
How I can select with sum from 2 tables? Like as:
ItemA 16
ItemB 9
ItemC 0
You can JOIN the table using a LEFT JOIN and apply an aggregate function SUM() to the price field:
select t1.item, IsNull(sum(t2.price), 0) total
from table1 t1
left join table2 t2
on t1.id = t2.itemid
group by t1.item
See SQL Fiddle with Demo
The LEFT JOIN will allow for the records not in the second table to be included in the final result. I added the IsNull() to the sum() to replace any null values with a zero.
Result:
| ITEM | TOTAL |
-----------------
| ItemA | 16 |
| ItemB | 9 |
| ItemC | 0 |
try this
select item,sum(price) from table1 left outer join table2
on table1.id=table2.itemid
group by item
Please try:
select a.Item, ISNULL(SUM(b.Price), 0) AS TOTALSum
from Table1 a LEFT JOIN Table2 b on a.Id=b.ItemId
Group by a.Item