I have two tables, customer and customer_order
customer
cust_id, cust_name
121 Acme Wholesalers
234 Griffen Electric
336 East Coast Marine Supplies
544 Sanford Automotive
customer_orders
order_num,cust_id,order_date
1 121 2019-01-15
2 234 2019-07-24
3 336 2020-05-02
4 121 2019-01-15
5 336 2020-03-19
6 234 2019-07-24
7 121 2019-01-15
8 336 2020-06-12
I need to find out the name of each customer who has placed exactly 3 orders but using a non-correlated subquery and without JOINS
I have got the same query results using correlated query
SELECT c.cust_name FROM customer c WHERE cust_id
IN (SELECT GROUP_CONCAT(cust_id) FROM customer_order )
but this time I need same results using non-correlated and without join also
seems like the big rock is finding cust_id values that have exactly three occurrences in customer_order we can do something like this
SELECT o.cust_id
FROM customer_orders o
GROUP
BY o.cust_id
HAVING COUNT(*) = 3
referencing the aggregate in a HAVING clause to restrict rows are returned.
we could use this query as an inline view (or, derived table, in the the mysql parlance), and then
SELECT n.cust_id
FROM (
-- cust_id that have exactly three rows
SELECT o.cust_id
FROM customer_orders o
GROUP
BY o.cust_id
HAVING COUNT(*) = 3
) n
and typically do a JOIN to the customers table to retrieve the name.
given a weird restriction of "no joins", we could (less optimally) use an WHERE foo IN (subquery) form
Hello everyone i will try to be as specific and precise as possible.
I was looking around for answer to my problem and in mean time i made 2 tables
In first table i have names of Companies and their id-s.
In second table i have names of Employees,their id-s,the cities in which they live,and idK-s(its supposed to match id id-s from previous table) of Companies they work in.
I am supposed to select names of Companies that have at least four(3 or more) employees living in different cities compared to each other.
In order for things to be more clear i am going to give an example:
table1:
id name
1 Company1
2 Company2
3 Company3
4 Company4
5 Company5
6 Company6
table2:
id name city idK
1 EMP1 city1 1
2 EMP2 city2 1
3 EMP3 city3 1
4 EMP4 city4 1
5 EMP5 city1 2
6 EMP6 city2 2
7 EMP7 city3 2
8 EMP8 city1 3
9 EMP9 city2 3
10 EMP10 city3 3
11 EMP11 city1 4
12 EMP12 city2 4
13 EMP13 city3 4
14 EMP14 city4 4
15 EMP15 city5 4
16 EMP16 city1 5
17 EMP17 city2 5
18 EMP18 city1 5
19 EMP19 city3 5
20 EMP20 city3 5
21 EMP21 city2 5
22 EMP22 city1 6
23 EMP23 city8 6
24 EMP24 city1 6
25 EMP25 city15 6
I made spaces so it is easier to see.
So in idK=1 we have four employees and all are from different city compared to each other so Company1 should be in results.
idK=2 and idK=3 have under four employees in general so Company2 and Company3 are out.
idK=4 is good same reasons as idK=1 but idK=5 and idK=6 are out because while they have four or more employees they are not from different cities compared to each other.
I found similar problems as mine and some solutions but none were good enough for me or i just couldn't make them work so i would be very grateful if someone could explain to me what to do in this situation.
This will work here.
select t1.name from table2 t2
inner join table1 t1 on t2.idK = t1.id
group by t2.idk,t1.name
having count(distinct city) > 3
This is the data I used to test on db-fiddle.
CREATE TABLE table2 (id int, name varchar(100), city varchar(100), idK int);
INSERT INTO table2 (id,name,city,idK)
VALUES (1,'EMP1','city1',1),
(2,'EMP2','city2',1),
(3,'EMP3','city3',1),
(4,'EMP4','city4',1),
(5,'EMP5','city1',2),
(6,'EMP6','city2',2),
(7,'EMP7','city3',2),
(8,'EMP8','city1',3),
(9,'EMP9','city2',3),
(10,'EMP10','city3',3),
(11,'EMP11','city1',4),
(12,'EMP12','city2',4),
(13,'EMP13','city3',4),
(14,'EMP14','city4',4),
(15,'EMP15','city5',4),
(16,'EMP16','city1',5),
(17,'EMP17','city2',5),
(18,'EMP18','city1',5),
(19,'EMP19','city3',5),
(20,'EMP20','city3',5),
(21,'EMP21','city2',5),
(22,'EMP22','city1',6),
(23,'EMP23','city8',6),
(24,'EMP24','city1',6),
(25,'EMP25','city15',6);
Create TABLE table1 (id int,name varchar(100));
INSERT INTO table1 (id,name)
VALUES (1,'Company1'),
(2,'Company2'),
(3,'Company3'),
(4,'Company4'),
(5,'Company5'),
(6,'Company6');
You can use count(DISTINCT columnname) to get the number of unique values in a column.
SELECT
c.`name`,
COUNT(DISTINCT e.`city`) as `Num Cities`
FROM `companies` c
JOIN `employees` e
ON c.`id` = e.`idK`
WHERE COUNT(DISTINCT e.`city`) > 3
GROUP BY c.`name`
ORDER BY c.`name`
I expect this is what you are looking for
select idk
from table2
group by idk
having count(distinct city) > 3
I am trying to do a multiplication operation in MySQL.
I have the following table called vehicul:
id car_type car_model number price car_id
1 audi <model1> 2 320 1
2 audi <model2> 4 100 1
3 bmw <model1> 3 240 2
4 bmw <model2> 6 500 2
5 bmw <model3> 1 400 2
I have this command:
SELECT car_type, sum(price) FROM vehicul as v, GROUP BY marca
Which displays the following:
car_type price
audi 420
bmw 1140
But what I want is to display the number * price and the result to be:
car_type price
audi 1040
bmw 4120
Basically.. sum(number*price).. how can I do that? I have tried doing:
SELECT car_type, sum(price*number) FROM vehicul as v, GROUP BY marca
But I am getting:
#1052 - Column 'number' in field list is ambiguous
select car_type, sum(price*number) as price from vehicul group by car_type..
http://sqlfiddle.com/#!2/3d881/1
you should use sum(field_1*field_2) instead of sum()*sum()
Your query is totally correct. You may have more than 1 table which contain 2 or more number column. Try:
SELECT car_type, sum(price)*sum(number)
FROM vehicul
GROUP BY marca;
But with the logic you will need this to get total price:
SELECT car_type, sum(price*number)
FROM vehicul
GROUP BY marca;
Whilst trying to do pagination I've run into this problem.
My table-
ID CarBrand Car Model
---------------------------
1 Alfa Romeo Guilietta
2 Alfa Romeo Mito
3 Audi A3
4 Audi R8
5 Audi TT
6 Fiat Punto
7 Fiat Panda
8 Ford Mondeo
9 Ford Mustang
10 Nissan Almera
11 Nissan Note
12 Nissan Qashqai
13 Toyota Aygo
14 Toyota Prius
15 Volkswagen Beetle
16 Volkswagen Golf
17 Volkswagen Polo
18 Volkswagen Up
I have the data displayed like so, in groups of two:
-Fiat - Punto
Panda
-Ford - Mondeo
Mustang
So there are 2 brands but 4 database results.
Is it possible to have a query limit and offset my results to two brands while showing all the models for the brand?
Sorry if I'm not clear!
It is clear. Try this:
select * from t t1
join (
select distinct carBrand from t
limit 2
) s on t1.carBrand = s.carBrand
Before the limit 2 apply the ordering you want.
To get a limit, without using the limit keyword, you can impose a count.
For example, given the table definition
create table cars (id int,
carBrand char(10),
carModel char(10));
this will give you all the Car Models for the top 2 Car Brands
select cars.carBrand, cars.carModel
from cars
where ((select count(*) from
(select distinct carBrand from cars) as carBrands
where carBrands.carBrand < cars.carBrand) < 2)
order by cars.carBrand, cars.carModel;
This creates an inline table just listing the carBrands and then joins this back to cars to get the list of all cars that are in the top 2 brands. The count(*) .... < 2 enforces the limit. Consider 'Ford', for example, in your above data. In 'Ford''s case, there are 3 brands that are < 'Ford' alphabetically, so the count(*) above = 3. Since 3 is not less than 2, no 'Ford' cars appear in the output.
The output on your test data would be:
CARBRAND CARMODEL
Alfa Romeo Guilietta
Alfa Romeo Mito
Audi A3
Audi R8
Audi TT
Now, you didn't say how you wanted to pick the 2 brands -- you just listed Ford and Fiat in your example -- I don't know how you happened to pick those. If you want something other than alphabetical criteria for ordering, that's doable, but harder.
SQL Fiddle and results for all this: http://sqlfiddle.com/#!2/33a8f/3
It's a matter of database design. Maybe you should split your data into two tables model (model names) and brand (brand names). Then you can write a query like this:
SELECT m.name, b.name
FROM model m
INNER JOIN brand b
WHERE b.id IN (
SELECT id
FROM brand
ORDER BY name ASC
LIMIT 2 OFFSET 0
)
I did not test the code. No need for GROUP BY in my opinion.
I have two tables, donaTypes and fullInfo.
fullInfo:
id funddesc giftamt giftdate
001 annual fund 50.00 2010-03-09
223 alumni fund 25.00 2009-03-06
334 capital exp 100.00 2011-09-27
... ... ... ...
donaTypes:
id donaType
1 annual fund
2 capital exp
3 alumni fund
I'm trying to match up where fullInfo.funddesc = donaTypes.donaType with the hope of inserting the donaTypes.id number into the fullInfo table. Here's my code but I just get a blank response (no error):
SELECT st1.funddesc, st2.donatype
FROM
(select t1.funddesc
from fullInfo as t1) st1
inner join
(select t2.donatype
from donatTypes as t2) st2
on trim(st1.funddesc) like trim(st2.donaType)
;
I also tried :
SELECT t1.funddesc, t2.donatype
FROM fullInfo as t1,
donatTypes as t2
where trim(t1.funddesc) = trim(t2.donatype);
Ideally, I'd like fullInfo to look like this:
fullInfo:
id funddesc giftamt giftdate
001 1 50.00 2010-03-09
223 3 25.00 2009-03-06
334 2 100.00 2011-09-27
... ... ... ...
Keep it a bit simpler til you get it debugged. You don't need the nested queries. And, LIKE is not really very good for joins, because it can be kind of promiscuous.
SELECT fi.funddesc, dt.donaType
FROM fullinfo fi
JOIN donatTypes dt on trim(fi.funddesc) = trim(dt.donaType)
You may also want to do this sort of thing on your two tables just to figure out what kind of stuff you actually have in your join columns.
SELECT COUNT(*), concat('>>>',TRIM(funddesc),'<<<')
FROM fullinfo
GROUP BY concat('>>>',TRIM(funddesc),'<<<')