I have two tables as mentioned below.
user table
id | username | password | status |
1 | Prajna | ***** | active |
2 | Akshata | ***** | active |
3 | Sanjana | ***** | inactive |
test table
id | project_name | created_by (user id) | edited_by (user id) |
1 | Test | 1 | 2 |
2 | Trial | 1 | 1 |
3 | Pro1 | 2 | 2 |
I am trying with below query.
select project_name, user.username from test join user on user.id=test.created_by where user.status='active';
I wanted the result like below
I want to retrieve the result as below
How can I retrieve?
project_name | username(created by) | username (edited by) |
Test | Prajna | Akshata |
Trial | Prajna | Prajna |
Pro1 | Akshata | Akshata |
Try this code.
create table `user`
(
`id` int,
`username` varchar(20),
`password` varchar(20),
`status` varchar(20)
)
insert into `user` (`id`,`username`,`password`,`status`) values
(1, 'Prajna', '*****', 'active'),
(2, 'Akshata', '*****', 'active'),
(3, 'Sanjana', '*****', 'inactive')
create table `test`
(
`id` int,
`project_name` varchar(20),
`created_by` int,
`edited_by` int
)
insert into `test` (`id`,`project_name`,`created_by`,`edited_by`) values
(1, 'Test', 1, 2),
(2, 'Trial', 1, 1),
(3, 'Pro1', 2, 2)
SELECT
`t`.`project_name`,
`ua`.`username` as 'username (created by)' ,
`ub`.`username` as 'username (edited by)'
FROM `test` `t`
JOIN `user` `ua` ON `t`.`created_by` = `ua`.`id`
JOIN `user` `ub` ON `t`.`edited_by` = `ub`.`id`
WHERE
`ua`.`status` = 'active'
AND `ub`.`status` = 'active'
order by `t`.`id`
project_name | username (created by) | username (edited by)
:----------- | :-------------------- | :-------------------
Test | Prajna | Akshata
Trial | Prajna | Prajna
Pro1 | Akshata | Akshata
db<>fiddle here
SELECT
test.project_name, user.username
FROM test
INNER JOIN user
ON user.id = test.created_by
WHERE user.status='active';
PS: you have an error here user.id=test=created_by
.
You need sub-query and join between those two sub-query using join
select project_name,created_by,edited_by from
(
select u.id,project_name, u.username as created_by from user u left join test t1 on
u.id= t1.created_by
where user.status='active'
) Table1
inner join
(
select u.id,project_name, u.username as edited_by from user u left join test t2 on
u.id= t2.created_by
where user.status='active'
) table2 on Table1.project_name=table2.project_name
Related
I have a schema as follows;
CREATE TABLE `vehicle` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`vehiclelicence` varchar(50) DEFAULT NULL,
`userid` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(50) DEFAULT NULL,
`companyid` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `company` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id`)
);
insert into vehicle (vehiclelicence, userid) values ('PB1234', 1);
insert into vehicle (vehiclelicence, userid) values ('AB0987', 2);
insert into vehicle (vehiclelicence, userid) values ('UI7654', 3);
insert into vehicle (vehiclelicence, userid) values ('DV8888', 4);
insert into vehicle (vehiclelicence, userid) values ('PB1234', 2);
insert into vehicle (vehiclelicence, userid) values ('UI7654', 1);
insert into user (username, companyid) values ('Bob', 1);
insert into user (username, companyid) values ('Tim', 2);
insert into user (username, companyid) values ('Jim', 3);
insert into user (username, companyid) values ('Fred', 4);
insert into company (name) values ('Company 1');
insert into company (name) values ('Company 2');
insert into company (name) values ('Company 3');
insert into company (name) values ('Company 4');
Users add vehiclelicences all the time.
How can I return all vehiclelicences listed by more than one company and which company listed it?
This is the sql I have so far, but it lists all the records.
SELECT *
FROM vehicle v1
join user u on u.id = v1.userid
join company c on c.id = u.companyid
WHERE EXISTS
(
SELECT 1
FROM vehicle v2
WHERE v1.vehiclelicence = v1.vehiclelicence and v2.userid != v1.userid
LIMIT 1, 1
)
order by v1.vehiclelicence
;
I have created a Fiddle
This is the desired output
+----------------+--------+----------+-----------+-------------+
| vehiclelicence | userid | username | companyid | companyname |
+----------------+--------+----------+-----------+-------------+
| PB1234 | 1 | Bob | 1 | Company 1 |
| PB1234 | 2 | Tim | 2 | Company 2 |
| UI7654 | 3 | Jim | 3 | Company 3 |
| UI7654 | 1 | Bob | 1 | Company 1 |
+----------------+--------+----------+-----------+-------------+
Thank you.
WHERE v1.vehiclelicence = v1.vehiclelicence - a typo here..and remove the limit and it works.
SELECT *
FROM vehicle v1
join user u on u.id = v1.userid
join company c on c.id = u.companyid
WHERE EXISTS
(
SELECT 1
FROM vehicle v2
WHERE v1.vehiclelicence = v2.vehiclelicence and v2.userid != v1.userid
#LIMIT 1, 1
)
order by v1.vehiclelicence
;
OR start the offset from 0
SELECT *
FROM vehicle v1
join user u on u.id = v1.userid
join company c on c.id = u.companyid
WHERE EXISTS
(
SELECT 1
FROM vehicle v2
WHERE v1.vehiclelicence = v2.vehiclelicence and v2.userid != v1.userid
LIMIT 0, 1
)
order by v1.vehiclelicence
;
either way
+----+----------------+--------+----+----------+-----------+----+-----------+
| id | vehiclelicence | userid | id | username | companyid | id | name |
+----+----------------+--------+----+----------+-----------+----+-----------+
| 1 | PB1234 | 1 | 1 | Bob | 1 | 1 | Company 1 |
| 5 | PB1234 | 2 | 2 | Tim | 2 | 2 | Company 2 |
| 6 | UI7654 | 1 | 1 | Bob | 1 | 1 | Company 1 |
| 3 | UI7654 | 3 | 3 | Jim | 3 | 3 | Company 3 |
+----+----------------+--------+----+----------+-----------+----+-----------+
4 rows in set (0.001 sec)
Taking into account the tables provided below, I want to be able to count the occurrences of how many Events a User still hasn't provided availability yet.
Table users
| name | id |
|---------|----|
| John | 1 |
| Francis | 2 |
| Peter | 3 |
| Mike | 4 |
Table events
| id | name |
|----|---------|
| 1 | Event 1 |
| 2 | Event 2 |
Table availability
| answer | event_id | user_id |
|--------|----------|---------|
| yes | 1 | 1 |
| yes | 2 | 1 |
| no | 1 | 2 |
| maybe | 2 | 4 |
The expected answer would then be:
Expected answer:
| user_id | count |
|---------|-------|
| 1 | 0 |
| 2 | 1 |
| 3 | 2 |
| 4 | 1 |
I have been able to do a query for how many events each member has responded, but looking for how many hasn't responded.
DBFiddle: https://www.db-fiddle.com/f/mwv4F1wYZ9UxB56L9mMjFQ/1
SQL:
create table events (
id int auto_increment primary key,
name varchar(100) null
);
create table users (
name varchar(100) null,
id int auto_increment primary key
);
create table availability (
answer text null,
event_id int null,
user_id int not null,
constraint availability_events_id_fk
foreign key (event_id) references events (id),
constraint availability_users_id_fk
foreign key (user_id) references users (id)
);
INSERT INTO events (id, name) VALUES (1, 'Event 1');
INSERT INTO events (id, name) VALUES (2, 'Event 2');
INSERT INTO users (name, id) VALUES ('John', 1);
INSERT INTO users (name, id) VALUES ('Francis', 2);
INSERT INTO users (name, id) VALUES ('Peter', 3);
INSERT INTO users (name, id) VALUES ('Mike', 4);
INSERT INTO availability (answer, event_id, user_id) VALUES ('yes', 1, 1);
INSERT INTO availability (answer, event_id, user_id) VALUES ('yes', 2, 1);
INSERT INTO availability (answer, event_id, user_id) VALUES ('no', 1, 2);
INSERT INTO availability (answer, event_id, user_id) VALUES ('maybe', 2, 4);
You can cross join tables users and events to generate all possible combinations, and then left join table availability. Then, aggregation and a conditional sum() give you the expected result.
select
u.id user_id,
sum(case when a.event_id is null then 1 else 0 end) cnt
from users u
cross join events e
left join availability a
on a.event_id = e.id and a.user_id = u.id
group by u.id
order by u.id
Demo on DB Fiddle:
user_id | cnt
------: | --:
1 | 0
2 | 1
3 | 2
4 | 1
You can also solve this by pre-aggregating the availability table:
select u.user_id, (e.num_events - a.cnt)
from users u left join
(select a.user_id, count(*) as cnt
from availability a
group by a.user_id
) a
on u.user_id = a.user_id cross join
(select count(*) as num_events from events) e;
I need to get all DISTINCT users excluding those who are not available according to unavailability periods of time.
The user table:
+------+-----------+--------------------------------------+
| id | firstname | content |
+------+-----------+--------------------------------------+
| 13 | John | ... |
| 44 | Marc | ... |
| 55 | Elise | ... |
+------+-----------+--------------------------------------+
The unavailability periods table:
+------+-----------+--------------+--------------+
| id | user_id | start | end |
+------+-----------+--------------+--------------+
| 1 | 13 | 2019-07-01 | 2019-07-10 |
| 2 | 13 | 2019-07-20 | 2019-07-30 |
| 3 | 13 | 2019-09-01 | 2019-09-30 |
| 4 | 44 | 2019-08-01 | 2019-08-15 |
+------+-----------+--------------+--------------|
For example, we want user who are available from 2019-06-20 to 2019-07-05: Marc and Elise are available.
Do I have to use a LEFT JOIN? This request is not working:
SELECT DISTINCT user.*, unavailability.start, unavailability.end,
FROM user
LEFT JOIN unavailability ON unavailability.user_id = user.id
WHERE
unavailability.start < "2019-06-20" AND unavailability.end > "2019-06-20"
AND unavailability.start < "2019-07-05" AND unavailability.end > "2019-07-05"
And I need as result:
+------+-----------+--------------------------------------+
| id | firstname | content |
+------+-----------+--------------------------------------+
| 44 | Marc | ... |
| 55 | Elise | ... |
+------+-----------+--------------------------------------+
With this request I don't get Elise who has no unavailability periods of time.
DROP TABLE IF EXISTS user;
CREATE TABLE user
(id SERIAL PRIMARY KEY
,firstname VARCHAR(12) NOT NULL UNIQUE
);
INSERT INTO user VALUES
(13,'John'),
(44,'Marc'),
(55,'Elise');
DROP TABLE IF EXISTS unavailability ;
CREATE TABLE unavailability
(id SERIAL PRIMARY KEY
,user_id INT NOT NULL
,start DATE NOT NULL
,end DATE NOT NULL
);
INSERT INTO unavailability VALUES
(1,13,'2019-07-01','2019-07-10'),
(2,13,'2019-07-20','2019-07-30'),
(3,13,'2019-09-01','2019-09-30'),
(4,44,'2019-08-01','2019-08-15');
SELECT x.*
FROM user x
LEFT
JOIN unavailability y
ON y.user_id = x.id
AND y.start <= '2019-07-05'
AND y.end >= '2019-06-20'
WHERE y.id IS NULL;
+----+-----------+
| id | firstname |
+----+-----------+
| 44 | Marc |
| 55 | Elise |
+----+-----------+
2 rows in set (0.01 sec)
This approach can be used:
select * from user k
where not exists (
select 1 from user
join unavailability u on u.user_id = user.id
and ('2019-06-20' between start and end or '2019-07-05' between start and end)
where user.id = k.id)
You can select the ids of the unavailables and use this result in a subquery :
Schema (MySQL v5.7)
CREATE TABLE user (
`id` INTEGER,
`firstname` VARCHAR(5),
`content` VARCHAR(3)
);
INSERT INTO user
(`id`, `firstname`, `content`)
VALUES
(13, 'John', '...'),
(44, 'Marc', '...'),
(55, 'Elise', '...');
CREATE TABLE unavailability (
`id` INTEGER,
`user_id` INTEGER,
`start` DATETIME,
`end` DATETIME
);
INSERT INTO unavailability
(`id`, `user_id`, `start`, `end`)
VALUES
(1, 13, '2019-07-01', '2019-07-10'),
(2, 13, '2019-07-20', '2019-07-30'),
(3, 13, '2019-09-01', '2019-09-30'),
(4, 44, '2019-08-01', '2019-08-15');
Query #1
SELECT *
FROM user us
WHERE us.id NOT IN (
SELECT u.user_id
FROM unavailability u
WHERE u.start <= '2019-07-05' AND u.end >= '2019-06-20'
);
| id | firstname | content |
| --- | --------- | ------- |
| 44 | Marc | ... |
| 55 | Elise | ... |
View on DB Fiddle
Note
This condition :
unavailability.start < 2019-06-20 AND unavailability.end > 2019-06-20
AND unavailability.start < 2019-07-05 AND unavailability.end > 2019-07-05
Will be evaluated like this :
unavailability.start < 2019-06-20 AND unavailability.end > 2019-07-05
Because, for the parts unavailability.start < 2019-06-20 AND unavailability.start < 2019-07-05, everything below 2019-07-05 but above 2019-06-20 will be excluded (you are using AND). The same for both unavailability.end
I have this
+---------+--------+-------+
| article | name |status |
+---------+--------+-------+
| 0001 | A | enable|
| 0002 | A | temp |
| 0003 | B | enable|
| 0004 | C | enable|
+---------+--------+-------+
I want to select all from this table 'product' but I want to group by name and if there is a status temp I want to ignore the enable status and display only the product with the temp status
This result after query will be :
+---------+--------+-------+
| article | name |status |
+---------+--------+-------+
| 0002 | A | temp |
| 0003 | B | enable|
| 0004 | C | enable|
+---------+--------+-------+
Could you help me to build this query ?
If find at least one temp in group, show it. Else show enable
select article, name, if(sum(status='temp'), 'temp', 'enable')
from thetable
group by name
To get article corresponding to temp status, use such query
select * from table1
where status = 'temp'
union
select * from table1
where name not in (select distinct name from table1 where status = 'temp' )
Try this, hope help for you;)
SQL Fiddle
MySQL 5.6 Schema:
CREATE TABLE table1
(`article` int, `name` varchar(1), `status` varchar(6))
;
INSERT INTO table1
(`article`, `name`, `status`)
VALUES
(0001, 'A', 'enable'),
(0002, 'A', 'temp'),
(0003, 'B', 'enable'),
(0004, 'C', 'enable')
;
Query 1:
select t1.*
from table1 t1
inner join (
select count(distinct status) cnt, name, group_concat(status) as names from table1 group by name
) t2 on t1.name = t2.name
and (t2.cnt = 1 or (find_in_set('temp', names) > 0 and t1.status = 'temp'))
group by t1.name, t1.status
Results:
| article | name | status |
|---------|------|--------|
| 2 | A | temp |
| 3 | B | enable |
| 4 | C | enable |
I'm having a problem with my query by selecting the rows with unique id in one column.
Here's my db looks like:
Table 1
user_id | user_name | user_email
1 john ex0#email
2 nathel ex1#email
3 bob ex2#email
Table 2
subs_id | user_id | prod_id
1 1 1
2 1 2
3 2 1
4 3 1
5 3 3
Table 3
prod_id | prod_name
1 Platinum
2 Gold
3 Steel
What I need to do is to select the user row from Table 1 join with Table 2 & 3 that has a unique record in Table 2 user_id column based on their subscription.
Example. I want to select the user subscribing only in platinum, so the output must be looks like this :
user_id | user_name | user_email | subs_id | user_id | prod_id | prod_id | prod_name
2 nathel ex1#email 3 2 1 1 Platinum
SELECT * from users u inner join subscription s on u.user_id = s.user_id
inner join products p on p.prod_id = s.prod_id
WHERE s.user_id IN (SELECT user_id from subscription GROUP by user_id HAVING count(user_id) = 1) AND s.prod_id = 1
The last piece of the puzzle has been omitted as an exercise for the reader...
DROP TABLE IF EXISTS users;
CREATE TABLE users
(user_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
,user_name VARCHAR(20) NOT NULL UNIQUE
,user_email VARCHAR(12) NOT NULL
);
INSERT INTO users VALUES
(1 ,'john','ex0#email'),
(2 ,'nathel','ex1#email'),
(3 ,'bob','ex2#email');
DROP TABLE IF EXISTS product_user;
CREATE TABLE product_user
(product_id INT NOT NULL
,user_id INT NOT NULL
,PRIMARY KEY (product_id,user_id)
);
INSERT INTO product_user VALUES
(1, 1),(2 ,1),(1 ,2),(1,3),(3,3);
DROP TABLE IF EXISTS products;
CREATE TABLE products
(product_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,product_name VARCHAR(12) NOT NULL UNIQUE);
INSERT INTO products VALUES (1 ,'Platinum'),(2,'Gold'),(3,'Steel');
SELECT *
FROM product_user x
LEFT
JOIN product_user y
ON y.user_id = x.user_id
AND y.product_id <> x.product_id
WHERE x.product_id =1;
+------------+---------+------------+---------+
| product_id | user_id | product_id | user_id |
+------------+---------+------------+---------+
| 1 | 1 | 2 | 1 |
| 1 | 2 | NULL | NULL |
| 1 | 3 | 3 | 3 |
+------------+---------+------------+---------+
SELECT *
FROM product_user x
LEFT
JOIN product_user y
ON y.user_id = x.user_id
AND y.product_id <> x.product_id
JOIN users u
ON u.user_id = x.user_id
JOIN products p
ON p.product_id = x.product_id
WHERE p.product_name = 'Platinum';
+------------+---------+------------+---------+---------+-----------+------------+------------+--------------+
| product_id | user_id | product_id | user_id | user_id | user_name | user_email | product_id | product_name |
+------------+---------+------------+---------+---------+-----------+------------+------------+--------------+
| 1 | 1 | 2 | 1 | 1 | john | ex0#email | 1 | Platinum |
| 1 | 2 | NULL | NULL | 2 | nathel | ex1#email | 1 | Platinum |
| 1 | 3 | 3 | 3 | 3 | bob | ex2#email | 1 | Platinum |
+------------+---------+------------+---------+---------+-----------+------------+------------+--------------+
Hope so you are looking for this :
SELECT * FROM table1 as t1
inner join table2 as t2 on t1.user_id = t2.user_id
inner join table3 as t3 on t2.prod_id = t3.prod_id
where t3.prod_name = 'Platinum';
I think you can use DISTINCT to fetch unique recodes from database in query
SELECT DISTINCT
t1.`user_id` ,t1.`user_name`,t1.`user_email`,t2.`subs_id`,t2.`user_id`,t2.`prod_id`,t3.`prod_id` ,t3.`prod_name`
FROM Table1 t1
INNER JOIN Table2 t2
ON t1.`user_id`=t2.`user_id`
INNER JOIN Table3 t3
ON t2.`prod_id`=t3.`prod_id`
WHERE
t1.`user_id`='2'
Hope this will be helpful to you
Please! try below code snip
select t1.user_id ,t1.user_name,t1.user_email,
t2.subs_id,t2.user_id , t2.prod_id ,
t3.prod_id , t3.prod_name
from table2 t2 inner join table1 t1 on t2.user_id=t1.user_id
inner join table3 t3 on t3.prod_id=t2.prod_id and t2.prod_id =1