I have the following table
postgres=# select * from joins_example;
user_id | price | id | email
---------+--------+----+--------------------------
1 | $30.00 | |
5 | $50.00 | |
7 | $20.00 | |
| | 1 | hadil#example.com
| | 5 | saiid#example.com
| | 2 | fahir#example.com
6 | $60.00 | 6 | oma#example.com
8 | $40.00 | 8 | nasim#example.com
| | 8 | nasim.hassan#example.com
9 | $40.00 | 9 | farah#example.com
9 | $70.00 | |
10 | $80.00 | | majid#example.com
| | 10 | majid.seif#example.com
(13 rows)
A self inner join between user_id and id produces
postgres=# select * from joins_example as x inner join joins_example as y on x.user_id = y.id;
user_id | price | id | email | user_id | price | id | email
---------+--------+----+-------------------+---------+--------+----+--------------------------
1 | $30.00 | | | | | 1 | hadil#example.com
5 | $50.00 | | | | | 5 | saiid#example.com
6 | $60.00 | 6 | oma#example.com | 6 | $60.00 | 6 | oma#example.com
8 | $40.00 | 8 | nasim#example.com | | | 8 | nasim.hassan#example.com
8 | $40.00 | 8 | nasim#example.com | 8 | $40.00 | 8 | nasim#example.com
9 | $40.00 | 9 | farah#example.com | 9 | $40.00 | 9 | farah#example.com
9 | $70.00 | | | 9 | $40.00 | 9 | farah#example.com
10 | $80.00 | | majid#example.com | | | 10 | majid.seif#example.com
(8 rows)
What I want is either:
user_id | price | id | email | user_id | price | id | email
---------+--------+----+-------------------+---------+--------+----+--------------------------
7 | $50.00 | | | | | |
| | | | | | 2 | fahir#example.com
or:
user_id | price | id | email | user_id | price | id | email
---------+--------+----+-------------------+---------+--------+----+--------------------------
| | | | 7 | $50.00 | |
| | 2 | fahir#example.com | | | |
Even
user_id | price | id | email
---------+--------+----+--------------------------
5 | $50.00 | |
| | 2 | fahir#example.com
would be a good start.
Specifically I want to know how to select only the rows from joins_example with user_ids or ids that don't exist in the inner join.
You could consider an approach that uses correlated subqueries with NOT EXISTS conditions:
select *
from joins_example as x
where
(
x.user_id is not null
and not exists (
select 1 from joins_example y where x.user_id = y.id
)
)
or (
x.id is not null
and not exists (
select 1 from joins_example y where x.id = y.user_id
)
)
Demo on DB Fiddle:
| user_id | price | id | email |
| ------- | ----- | --- | ----------------- |
| 7 | 20.00 | | |
| | | 2 | fahir#example.com |
SELECT *
FROM joins_example j
WHERE (j.user_id IS NULL AND j.id IS NULL)
OR (j.user_id IS NOT NULL AND NOT EXISTS(SELECT 1 FROM joins_example j2 WHERE j2.id = j.user_id))
OR (j.id IS NOT NULL AND NOT EXISTS(SELECT 1 FROM joins_example j2 WHERE j2.user_id = j.id));
SELECT *
FROM joins_example AS w
LEFT JOIN (
select x.user_id
from joins_example as x
inner join joins_example as y on x.user_id = y.id
) AS z ON z.user_id = w.user_id or z.user_id = w.id
WHERE z.user_id IS NULL;
Is a good enough start i.e.
user_id | price | id | email | user_id
---------+--------+----+-------------------+---------
7 | $20.00 | | |
| | 2 | fahir#example.com |
Can you help me on what query I to to update one table with data from another.
I have 2 tables for example:
tbl_med_take
| id | name | med | qty |
---------------------------------
| 1 | jayson | med2 | 3 |
| 2 | may | med2 | 4 |
| 3 | jenny. | med3 | 6 |
| 4 | joel. | med3 | 4 |
tbl_med
| id | med | stocks |
-----------------------------
| 1 | med1 | 20 |
| 2 | med2 |. 17 |
| 3 | med3 | 24 |
The output that I want in tbl_med:
tbl_med
| id | med | stocks |
-----------------------------
| 1 | med1 | 20 |
| 2 | med2 |. 10 |
| 3 | med3 | 14 |
First get the total consumed from med_tbl_take using
select med,sum(quantity) as total from tbl_med_take group by med
Then you can left join with your med_tbl and subtract.
select m.id,m.med,(m.stocks-ISNULL(n.total,0)) from tbl_med m
left join
(select med,sum(quantity) as total from tbl_med_take group by med) n
on m.med=n.med
CHECK DEMO HERE
I have the following four tables:
1) mls_user
2) mls_category
3) bonus_point
4) mls_entry
In mls_user table values are like below:
*-------------------------*
| id | store_id | name |
*-------------------------*
| 1 | 101 | sandeep |
| 2 | 101 | gagan |
| 3 | 102 | santosh |
| 4 | 103 | manu |
| 5 | 101 | jagveer |
*-------------------------*
In mls_category table values are like below:
*---------------------------------*
| cat_no | store_id | cat_value |
*---------------------------------*
| 20 | 101 | 1 |
| 21 | 101 | 4 |
| 30 | 102 | 1 |
| 31 | 102 | 2 |
| 40 | 103 | 1 |
| 41 | 103 | 1 |
*---------------------------------*
In bonus_point table values are like below:
*-----------------------------------*
| user_id | store_id | bonus_point |
| 1 | 101 | 10 |
| 4 | 101 | 5 |
*-----------------------------------*
In mls_entry table values are like below:
*-------------------------------------------------------*
| user_id | store_id | category | distance | status |
*-------------------------------------------------------*
| 1 | 101 | 20 | 10 | Approved |
| 1 | 101 | 21 | 40 | Approved |
| 1 | 101 | 20 | 10 | Approved |
| 2 | 101 | 20 | 5 | Approved |
| 3 | 102 | 30 | 10 | Approved |
| 3 | 102 | 31 | 80 | Approved |
| 4 | 101 | 20 | 15 | Approved |
*-------------------------------------------------------*
And I want below output:
*--------------------------------------------------*
| user name | Points | bonus Point | Total Point |
*--------------------------------------------------*
| Sandeep | 30 | 10 | 40 |
| Santosh | 30 | 0 | 30 |
| Manu | 15 | 5 | 20 |
| Gagan | 5 | 0 | 5 |
| Jagveer | 0 | 0 | 0 |
*--------------------------------------------------*
I tell the calculation of how the points will come for user Sandeep.
Points = ((10+10)/1 + 40/4)=30
Here 1 and 4 is cat value which comes from mls_category.
I am using below code for a particular user but when i
SELECT sum(t1.totald/c.cat_value) as total_distance
FROM mls_category c
join (
select sum(distance) totald, user_id, category
FROM mls_entry
WHERE user_id=1 AND store_id='101' AND status='approved'
group by user_id, category) t1 on c.cat_no = t1.category
I have created tables in online for checking
DEMO
Computing the points (other than the bonus points) requires a separate join between the mls_entry and mls_category tables. I would do this in a separate subquery, and then join this to the larger query.
Here is one approach:
SELECT
u.name,
COALESCE(t1.points, 0) AS points,
COALESCE(b.bonus_point, 0) AS bonus_points,
COALESCE(t1.points, 0) + COALESCE(b.bonus_point, 0) AS total_points
FROM mls_user u
LEFT JOIN
(
SELECT e.user_id, SUM(e.distance / c.cat_value) AS points
FROM mls_entry e
INNER JOIN mls_category c
ON e.store_id = c.store_id AND e.category = c.cat_no
GROUP BY e.user_id
) t1
ON u.id = t1.user_id
LEFT JOIN bonus_point b
ON u.id = b.user_id
ORDER BY
total_points DESC;
This is the output I am getting from the above query in the demo you setup:
The output does not match exactly, because you have (perhaps) a typo in Santosh's data in your question, or otherwise the expected output in your question has a typo.
I want to create a view that present only the results and not present the duplicates, I have 3 tables in oracle database:
The first table contain general information about a person
+-----------+-------+-------------+
| ID | Name | Birtday_date|
+-----------+-------+-------------+
| 1 | Byron | 12/10/1998 |
| 2 | Peter | 01/11/1973 |
| 4 | Jose | 05/02/2008 |
+-----------+-------+-------------+
The second table contain information about a telephone of the people in the first table.
+-------+----------+----------+----------+
| ID |ID_Person |CELL_TYPE | NUMBER |
+-------+- --------+----------+----------+
| 1221 | 1 | 3 | 099141021|
| 2221 | 1 | 2 | 099091925|
| 3222 | 1 | 1 | 098041013|
| 4321 | 2 | 1 | 088043153|
| 4561 | 2 | 2 | 090044313|
| 5678 | 4 | 1 | 092049013|
| 8990 | 4 | 2 | 098090233|
+----- -+----------+----------+----------+
The Third table contain information about a email of the people in the first table.
+------+----------+----------+---------------+
| ID |ID_Person |MAIL_TYPE | Email |
+------+- --------+----------+---------------+
| 221 | 1 | 1 |jdoe#aol.com |
| 222 | 1 | 2 |jdoe1#aol.com |
| 421 | 2 | 1 |xx12#yahoo.com |
| 451 | 2 | 2 |dsdsa#gmail.com|
| 578 | 4 | 1 |sasaw1#sdas.com|
| 899 | 4 | 2 |cvcvsd#wew.es |
+------+----------+----------+---------------+
if i do a inner join with this tables the result will do something like that
+-----+-------+-------------+----------+----------+----------+----------------+
| ID | Name | Birtday_date| CELL_TYPE| NUMBER |MAIL_TYPE|Email |
+-----+-------+-------------+----------+----------+----------+----------------+
| 1 | Byron | 12/10/1998 | 3 | 099141021|1 |jdoe#aol.com |
| 1 | Byron | 12/10/1998 | 3 | 099141021|2 |jdoe1#aol.com |
| 1 | Byron | 12/10/1998 | 2 | 099091925|1 |jdoe#aol.com |
| 1 | Byron | 12/10/1998 | 2 | 099091925|2 |jdoe1#aol.com |
| 1 | Byron | 12/10/1998 | 1 | 098041013|1 |jdoe#aol.com |
| 1 | Byron | 12/10/1998 | 1 | 098041013|2 |jdoe1#aol.com |
| 2 | Peter | 01/11/1973 | 1 | 088043153|1 |xx12#yahoo.com |
| 2 | Peter | 01/11/1973 | 1 | 088043153|2 |dsdsa#gmail.com |
| 2 | Peter | 01/11/1973 | 2 | 090044313|1 |xx12#yahoo.com |
| 2 | Peter | 01/11/1973 | 2 | 090044313|2 |dsdsa#gmail.com |
| 4 | Jose | 05/02/2008 | 1 | 088043153|1 |sasaw1#sdas.com |
| 4 | Jose | 05/02/2008 | 1 | 088043153|2 |cvcvsd#wew.es |
| 4 | Jose | 05/02/2008 | 2 | 088043153|1 |sasaw1#sdas.com |
| 4 | Jose | 05/02/2008 | 2 | 088043153|2 |cvcvsd#wew.es |
+-----+-------+-------------+----------+----------+----------+----------------+
So the result that i will to present in a view is the next
+-----+-------+-------------+----------+----------+----------+----------------+
| ID | Name | Birtday_date| CELL_TYPE| NUMBER |MAIL_TYPE|Email |
+-----+-------+-------------+----------+----------+----------+----------------+
| 1 | Byron | 12/10/1998 | 3 | 099141021|1 |jdoe#aol.com |
| 1 | Byron | 12/10/1998 | | |2 |jdoe1#aol.com |
| 1 | Byron | 12/10/1998 | 2 | 099091925| | |
| 1 | Byron | 12/10/1998 | 1 | 098041013| | |
| 2 | Peter | 01/11/1973 | 1 | 088043153|1 |xx12#yahoo.com |
| 2 | Peter | 01/11/1973 | | |2 |dsdsa#gmail.com |
| 2 | Peter | 01/11/1973 | 2 | 090044313| | |
| 4 | Jose | 05/02/2008 | 1 | 092049013|1 |sasaw1#sdas.com |
| 4 | Jose | 05/02/2008 | | |2 |cvcvsd#wew.es |
| 4 | Jose | 05/02/2008 | 2 | 098090233| | |
+-----+-------+-------------+----------+----------+----------+----------------+
I tried to achieve a similar output using
case
when row_number() over (partition by table1.id order by table2.type) = 1
then table1.value
end
as "VALUE"
But the result is nothing that I expect and some rows they repeats
What you need to do is enumerate the rows and then join on those enumerations. This is tricky, because you don't know how many are in each list. Well, there is another method using conditional aggregation:
select p.id, p.name, p.birthday,
max(cell_type) as cell_type, max(number) as number,
max(mail_type) as mail_type, max(email) as email
from person p left join
((select id_person, cell_type, number,
null as mail_type, null as email,
row_number() over (partition by id_person order by number) as seqnum
from phones
) union all
(select id_person, null as cell_type, null as number,
mail_type, email,
row_number() over (partition by id_person order by email) as seqnum
from emails
)
) pe
on pe.id_person = p.id_person
group by p.id, p.name, p.birthday, pe.seqnum
Hope this helps.
Create table person(ID int ,Name varchar(20), Birtday_date date)
Insert into person values
(1,'Byron' ,'12/10/1998'),
(2,'Peter' ,'01/11/1973'),
(4,'Jose ' ,'05/02/2008')
Create table phones (ID int,ID_Person int,CELL_TYPE int,NUMBER float)
Insert into phones values
(1221, 1 , 3,099141021),
(2221, 1 , 2,099091925),
(3222, 1 , 1,098041013),
(4321, 2 , 1,088043153),
(4561, 2 , 2,090044313),
(5678, 4 , 1,092049013),
(8990, 4 , 2,098090233)
Create table emails(ID int,ID_Person int, MAIL_TYPE int, Email varchar(100))
Insert into emails values
(221, 1 , 1, 'jdoe#aol.com '),
(222, 1 , 2, 'jdoe1#aol.com '),
(421, 2 , 1, 'xx12#yahoo.com '),
(451, 2 , 2, 'dsdsa#gmail.com'),
(578, 4 , 1, 'sasaw1#sdas.com'),
(899, 4 , 2, 'cvcvsd#wew.es ')
select p.id, p.name, p.Birtday_date,
case when Lag(number) over(partition by p.id order by p.id,pe.id) = number then null else cell_type end as cell_type,
case when Lag(number) over(partition by p.id order by p.id,pe.id) = number then null else number end as number,
mail_type as mail_type, email as email
from person p left join
(select pp.ID_Person, cell_type, number, mail_type, email,pp.id from
(select ID_Person, cell_type, number,id,
row_number() over (partition by ID_Person order by id ) as seqnum
from phones
) pp left join
(select ID_Person,
mail_type, email, 1 as seqnum
from emails
)e on pp.ID_Person = e.ID_Person and pp.seqnum = e.seqnum
) pe
on pe.ID_Person = p.Id
order by p.id, pe.id
I have 3 like with many - many relationship
As:
TABLE 1 : select * from student;
| id | name |
| 1 | sone |
| 2 | stwo |
| 3 | sthree |
| 4 | sfour |
| 6 | ssix |
TABLE 2 : select * from course;
| id | name |
| 100 | CSE |
| 101 | ECE |
| 102 | ITI |
RELATION_SHIP TABLE : select * from student_course
| id | stu_id | cou_id |
| 1 | 1 | 101 |
| 2 | 2 | 102 |
| 3 | 2 | 100 |
| 4 | 3 | 100 |
| 5 | 3 | 101 |
| 6 | 1 | 101 |
| 1 | 6 | 101 |
I need to write a query to select a student with exactly one course 'CSE' and he should not have any other courses.
Thanks in advance
Use query:
SELECT
sc.`stu_id`,
COUNT(sc.`cou_id`) AS cnt
FROM
student_course sc
GROUP BY sc.`stu_id`
HAVING cnt = 1
AND GROUP_CONCAT(cou_id) LIKE
(SELECT
id
FROM
course
WHERE NAME = 'CSE')