I've been struggling to come up with a solution to the following problem.
I have two tables with the following structure.
member table:
╔═══════════╦═════════════╦═════════╗
║ member_no ║ member_type ║ team_no ║
╠═══════════╬═════════════╬═════════╣
║ CON123 ║ monthly ║ 12 ║
╠═══════════╬═════════════╬═════════╣
║ CON456 ║ monthly ║ 13 ║
╠═══════════╬═════════════╬═════════╣
║ CON789 ║ annual ║ 13 ║
╚═══════════╩═════════════╩═════════╝
team table:
╔═════════╦════════════╦══════════════╗
║ team_no ║ supervisor ║ member_count ║
╠═════════╬════════════╬══════════════╣
║ 12 ║ John ║ 1 ║
╠═════════╬════════════╬══════════════╣
║ 13 ║ Joe ║ 2 ║
╠═════════╬════════════╬══════════════╣
║ 14 ║ Allan ║ 0 ║
╚═════════╩════════════╩══════════════╝
What I would like to do is something like this when inserting values into the "team" table:
INSERT INTO team (team_no , supervisor , member_count)
VALUES ("13" , "Joe" , SELECT COUNT(team_no) FROM member WHERE team_no = "13");
Essentially, I would like the member_count column from the "team" table to be populated with the total number of members belonging to that team using the COUNT function on the member table.
I'd be really thankful if anyone can help me with this problem.
you can use an INSERT / SELECT using this sintax
INSERT INTO team (team_no , supervisor , member_count)
select "13" , "Joe" , COUNT(team_no)
FROM member
WHERE team_no = "13"
see mysql doc for more https://dev.mysql.com/doc/refman/5.7/en/insert-select.html
You can basically do your query with additional parentheses:
INSERT INTO team (team_no , supervisor , member_count)
VALUES (13 , 'Joe' , (SELECT COUNT(team_no) FROM member WHERE team_no = 13));
Subqueries require their own parentheses.
Don't use single or double quotes for numbers.
Admittedly, I would probably use insert . . . select, but this is the smallest change to your attempted query.
Related
Subquery returns more than 1 row??
SELECT
`employee`.`employee_id` AS `employee_id`,
(
SELECT
SUM(company.company_profit_left)
FROM
company
GROUP BY
company.employee_id,
company.employee_department
) AS profit_left
FROM
employee
LEFT JOIN `company` ON `company`.`employee_id` = `employee`.`employee_id`
GROUP BY
`employee`.`employee_id`
HAVING
SUM(
company.company_profit_left
) = 0
╔════╦══════════════╦════════════╦════════════╦
║ id ║ user_id ║ profit left║ department ║
╠════╬══════════════╬════════════╬════════════╬
║ 1 ║ 1 ║ 100 ║ 1 ║
║ 2 ║ 2 ║ 50 ║ 1 ║
║ 3 ║ 1 ║ 30 ║ 2 ║
║ 4 ║ 2 ║ 20 ║ 1 ║
║ 5 ║ 2 ║ 20 ║ 3 ║
╚════╩══════════════╩════════════╩════════════╩
and the below table is what I want to achieve
╦══════════════╦══════════════╦
║ user_id ║ profit left ║
╠══════════════╬══════════════╬
║ 1 ║ 100 ║
║ 1 ║ 30 ║
║ 2 ║ 70 ║
║ 2 ║ 20 ║
╚══════════════╩══════════════╩
that's why I thought I needed to use group by to distinguish user_id
I have already looked at
Subquery returns more than 1 row - MySQL
subquery returns more than 1 row?
but still don't understand.
By joining two different tables, I get the below table.
anyone can help me solve the problem ?
Edit: Based on table structure and output required, I updated the query and removed unwanted where and left join.
I don't know what you're trying to do. But based on my understanding I corrected your query:
SELECT
employee.employee_id AS employee_id,
profit_left.employee_department
profit_left.company_profit
FROM
employee
JOIN (
SELECT
company.employee_id,
company.employee_department,
SUM(company.company_profit_left) as company_profit
FROM company
GROUP BY company.employee_id,company.employee_department
) AS profit_left on employee.employee_id=profit_left.employee_id
I think you want a correlated subquery. I'm not sure what you are really doing, but this should fix your error:
(SELECT SUM(company.company_profit_left)
FROM company c
WHERE c.employee_id = e.employee_id
) AS profit_left
You might want this by department instead. But the point is that aggregation is not appropriate for the subquery. A correlation clause is appropriate.
Your sub query grouping all the employee in company tabel and not one of them.you must put where condition in sub query to filter records and no need to grouping in sub query.
I searched so much to find an answer but i can't.Here is my question
I have a table named main_table like this:
╔════╦════════════════╦
║ id ║ seat_id ║
╠════╬════════════════╬
║ 1 ║ 274115, ║
║ 2 ║ 274116,274117,║
║ 3 ║ 274113,274114, ║
╚════╩════════════════╩
These seat_id's are primary key of another table named sub_table
╔═════════╦════════════════╦
║ seat_id ║ seat ║
╠═════════╬════════════════╬
║ 274115 ║ 186 ║
║ 274116 ║ 187 ║
║ 274117 ║ 188 ║
║ 274118 ║ 159 ║
╚═════════╩════════════════╩
I want all the seat related to main_table's seat_id
╔════════════╗
║ seat ║
╠════════════╣
║ 186 ║
║ 187 ║
║ 188 ║
╚════════════╝
What i have tried so far is with sub query
select seat from sub_table where seat_id in(select seat_id from main_table)
That's not helping me
You can use FIND_IN_SET:
SELECT seat
FROM sub_table AS t1
WHERE EXISTS (SELECT 1
FROM main_table AS t2
WHERE FIND_IN_SET(t1.seat_id, t2.seat_id) <> 0)
However, I would suggest normalizing table main_table, as it is always a bad idea to store comma separated values in a single field like you do.
Demo here
First of all u didnt normalize your table so u cant use joins
and query u used "select seat_id from main_table" --> is not an array .
Try to pass array
select seat from sub_table where seat_id in($array)
I'd like to merge rows based on multiple criteria, essentially removing duplicates where I get to define what "duplicate" means. Here is an example table:
╔═════╦═══════╦═════╦═══════╗
║ id* ║ name ║ age ║ grade ║
╠═════╬═══════╬═════╬═══════╣
║ 1 ║ John ║ 11 ║ 5 ║
║ 2 ║ John ║ 11 ║ 5 ║
║ 3 ║ John ║ 11 ║ 6 ║
║ 4 ║ Sam ║ 14 ║ 7 ║
║ 5 ║ Sam ║ 14 ║ 7 ║
╚═════╩═══════╩═════╩═══════╝
In my example, let's say I want to merge on name and age but ignore grade. The result should be:
╔═════╦═══════╦═════╦═══════╗
║ id* ║ name ║ age ║ grade ║
╠═════╬═══════╬═════╬═══════╣
║ 1 ║ John ║ 11 ║ 5 ║
║ 3 ║ John ║ 11 ║ 6 ║
║ 4 ║ Sam ║ 14 ║ 7 ║
╚═════╩═══════╩═════╩═══════╝
I don't particularly care if the id column is updated to be incremental, but I suppose that would be nice.
Can I do this in MySQL?
My suggestion, based on my above comment.
SELECT distinct name, age, grade
into tempTable
from theTable
This will ignore the IDs and give you only a distinct dump, and into a new table.
Then you can either drop the old and, and rename the new one. Or truncate the old one, and dump this back in.
You could just delete the duplicates in place like this:
delete test
from test
inner join (
select name, age, grade, min(id) as minid, count(*)
from test
group by name, age, grade
having count(*) > 1
) main on test.id = main.minid;
Example: http://sqlfiddle.com/#!9/f1a38/1
My head is turning to mush when trying to get this nesting around my head.
So basically I got 2 tables:
Brokers, which is my "user" table:
╔══════════╦════════════╦
║ ID ║ EMAIL ║
╠══════════╬════════════╬
║ 1 ║ 1#email.co ║
║ 2 ║ 2#email.co ║
║ 3 ║ 3#email.co ║
╚══════════╩════════════╝
Houses, which is houses that the users have added. Currently user and house is connected by the email column (I know, makes more sense to do with a ID):
╔══════════╦════════════╦════════════╦
║ ID ║ TYPE ║ EMAIL ║
╠══════════╬════════════╬════════════╬
║ 1 ║ 1 ║ 1#email.co ║
║ 2 ║ 3 ║ 1#email.co ║
║ 3 ║ 2 ║ 1#email.co ║
║ 4 ║ 3 ║ 1#email.co ║
║ 5 ║ 3 ║ 1#email.co ║
║ 6 ║ 2 ║ 1#email.co ║
║ 7 ║ 3 ║ 1#email.co ║
║ 8 ║ 1 ║ 2#email.co ║
║ 9 ║ 1 ║ 2#email.co ║
║ 10 ║ 2 ║ 2#email.co ║
║ 11 ║ 2 ║ 2#email.co ║
║ 12 ║ 3 ║ 2#email.co ║
║ 13 ║ 3 ║ 3#email.co ║
║ 14 ║ 2 ║ 3#email.co ║
║ 15 ║ 3 ║ 3#email.co ║
║ 16 ║ 1 ║ 3#email.co ║
║ 17 ║ 3 ║ 3#email.co ║
║ 18 ║ 2 ║ 3#email.co ║
║ 19 ║ 2 ║ 3#email.co ║
║ 20 ║ 3 ║ 3#email.co ║
╚══════════╩════════════╩════════════╝
Now what I want to do, is that I want to select all brokers that have type 3 as the highest, most popular kind of house added. So for example if house type 3 represents "Apartments", I want to find the brokers that sell apartments as their number one most popular type.
My current query is:
SELECT b.id, b.email, h.email, h.type, h.total
FROM brokers b
INNER JOIN (
SELECT COUNT( * ) AS total, email, type
FROM house
GROUP BY email, type
ORDER BY total DESC
)h ON b.email = h.email
AND h.type = "3"
ORDER BY b.id DESC
Now this only selects the total amount of houses that that broker has for type 3. It does not only select the brokers where type 3 is their most popular type.
Now to do that, I need to use what is called "Groupwise Max". But I can not use max() on a count(*) like:
MAX(COUNT(*)) as max_value
So I guess that what I need to do is to nest my query further with additional subqueries to first count, and then select the max value.
I've been trying to get it right for a while now and I just can't get my head around it. Anyone can help?
EDIT:
Expected Output:
Based on the table above, Broker 1#email.co got:
1 House with Type 1.
2 Houses with Type 2.
4 Houses with Type 3.
Broker 2#email.co got:
2 houses with Type 1
2 houses with Type 2
1 house with Type 3.
Broker 3#email.co got:
1 house with Type 1.
3 houses with Type 2.
4 houses with Type 3.
Since both 1#email.co and 3#email.co is selling House Type 3 most commonly, they should be included in the output. 2#email.co do not sell type 3 as his most popular type, so he should not be included in the result.
So output:
╔══════════╦════════════╦════════════╦
║ ID ║ EMAIL ║ Total ║
╠══════════╬════════════╬════════════╬
║ 1 ║ 1#email.co ║ 4 ║
║ 3 ║ 3#email.co ║ 4 ║
╚══════════╩════════════╝════════════╝
Posting answer without executing, hope this works!
Select a.ID,a.Email,b.Cnt from Brokers as a
inner join (
Select Email,count(ID) as Cnt from Houses where Type =
(Select max(Type) from Houses)
group by Email
) as b on a.Email = b.Email
I can't understand why you need Count()? I think, according to you question ("select all brokers that have type 3") , it doesn't make sense, or do I misunderstand something?
EDIT:
I have done it in SQL SERVER by temporary table and variable
If you can convert it to mysql syntax, your problem will we solved:
SELECT COUNT(*) as total, Email, [Type]
into #tbl3
from house
group by Email, Type
declare #a int
set #a = (select MAX(total) from #tbl3)
SELECT b.id, b.email, h.email, h.type, h.total
FROM brokers b
inner join
(
select * from #tbl3
where total=#a
) h
on h.Email=b.Email and h.Type=3
EDIT: This is MySql syntax which will do your job.
CREATE TEMPORARY TABLE IF NOT EXISTS table2 AS (
SELECT COUNT(*) as total, Email, Type
from house
group by Email, Type
);
set #a = (select MAX(total) from table2);
SELECT b.id, b.email, h.email, h.type, h.total
FROM brokers b
inner join
(
select * from table2
where total=#a
) h
on h.Email=b.Email and h.Type=3
My table has a list of users with Items associated to them. I hope to be able to consolidate the items field into a list or create another column if the row has a matching User/email.
I have the following structure with in the MySQL table:
╔═══════════╦═════════════╦═════════════╦═════════════╦═════════════╦════════════╗
║ ID ║ User_ID ║ Item ║ Date ║ User ║ Email ║
╠═══════════╬═════════════╬═════════════╬═════════════╬═════════════╬════════════╣
║ 1 ║ 1 ║ Laptop 1 ║ 30th Nov ║ John ║ J#test.com ║
║ 2 ║ 2 ║ Laptop 3 ║ 12th Nov ║ Emma ║ e#test.com ║
║ 3 ║ 2 ║ Camera 3 ║ 12th Nov ║ Emma ║ e#test.com ║
╚═══════════╩═════════════╩═════════════╩═════════════╩═════════════╩════════════╝
I am very new to SQL but i think i would need to use some type of transpose field to a column function?
Any help will be greatly appreciated
Thanks
I think you want group_concat(). Personally, I would use user_id, rather than user/email. or, perhaps all three together. Something like this:
select user_id, user, email, group_concat(item) as items
from table t
group by user_id, user, email;