Join ID names of one MySQL table to IDs in another - mysql

I have one table of client details identified by an ID that looks like this:
ID (the clientcode), Name, Details
I would like to reference the ID from another table with sales information and pick up the name of the client in the query.
My original query string that picked up just the ID (clientcode) is this:
SELECT clientcode, SUM(sales) FROM inventory WHERE manufacturer='1'
GROUP BY client code ORDER BY SUM(sales) DESC
I would like to also pick up the Name of the client referenced by clientcode.
I tried a few LEFT JOINs but couldn't get the queries working.

SELECT i.clientcode
, c.name
, SUM(i.sales)
FROM inventory i
LEFT
JOIN clientdetails c
ON c.id = i.clientcode
WHERE i.manufacturer='1'
GROUP BY i.clientcode, c.name
ORDER BY SUM(i.sales) DESC

This should do it
SELECT c.ID, c.name, SUM(i.sales)
FROM inventory i
JOIN clients c ON c.ID = i.clientcode
WHERE i.manufacturer='1'
GROUP BY c.ID, ORDER BY SUM(i.sales) DESC

A simple query to achieve this is:
SELECT i.clientcode, d.name, SUM(i.sales) FROM inventory i, details d
WHERE i.manufacturer='1'
AND d.clientcode = i.clientcode
GROUP BY i.clientcode ORDER BY SUM(i.sales) DESC

Here, try thisone out.
SELECT inventory.clientcode,
SUM(inventory.sales),
clientdetails.Name
FROM inventory
INNER JOIN clientdetails
ON inventory.clientcode = clientdetails.clientcode
WHERE inventory.manufacturer='1'
GROUP BY inventory.clientcode, clientdetails.Name
ORDER BY SUM(inventory.sales) DESC

SELECT a.clientcode,
SUM(a.sales),
b.Name
FROM inventory a
INNER JOIN clientdetails b
ON a.clientcode = b.clientcode
WHERE a.manufacturer='1'
GROUP BY a.clientcode, b.Name
ORDER BY SUM(a.sales) DESC

Related

Subquery left join refer to parent ID

I am trying to make a query to fetch the newest car for each user:
select * from users
left join
(select cars.* from cars
where cars.userid=users.userid
order by cars.year desc limit 1) as cars
on cars.userid=users.userid
It looks like it says Unknown column "users.userid" in where clause
I tried to remove cars.userid=users.userid part, but then it only fetches 1 newest car, and sticks it on to each user.
Is there any way to accomplish what I'm after? thanks!!
For this purpose, I usually use row_number():
select *
from users u left join
(select c.* , row_number() over (partition by c.userid order by c.year desc) as seqnum
from cars c
) c
on c.userid = u.userid and c.seqnum = 1;
One option is to filter the left join with a subquery:
select * -- better enumerate the columns here
from users u
left join cars c
on c.userid = u.userid
and c.year = (select max(c1.year) from cars c1 where c1.userid = c.userid)
For performance, consider an index on car(userid, year).
Note that this might return multiple cars per user if you have duplicate (userid, year) in cars. It would be better to have a real date rather than just the year.
Maybe there are better and more efficient way to query this. Here is my solution;
select users.userid, cars.*
from users
left join cars on cars.userid = users.userid
join (SELECT userid, MAX(year) AS maxDate
FROM cars
GROUP BY userid) as sub on cars.year = sub.maxDate;

How to get first value from this sql query

Im trying to get by subquery clientId of customer with most orders but only one expression can be specified in the select list when the subquery is not introduced with EXISTS.
SELECT a.ClientName
FROM Clients as a
INNER JOIN Orders as b
ON a.Id=b.ClientId
WHERE b.ClientId
IN(SELECT b.ClientId,COUNT( b.ClientId) as MAKS FROM Orders as b
GROUP BY b.ClientId ORDER BY MAKS DESC)
Do we have some tools to handle this and how can i optimize this query? Thanks in advance.
You don't really need the inner join because you are asking for an ID that is the same in both tables,
SELECT ClientName FROM Clients
WHERE Id = (SELECT TOP 1 ClientId FROM Orders
GROUP BY ClientId
ORDER BY COUNT(ClientId) DESC)
Using Top 1, Count and Group By
SQL Server
SELECT Top 1 a.ClientName , count(b.orders_id) TotalOrders
FROM Clients as a
INNER JOIN Orders as b
ON a.Id=b.ClientId
GROUP BY a.client_name
order by TotalOrders desc
MySQL
SELECT a.ClientName , count(b.orders_id) TotalOrders
FROM Clients as a
INNER JOIN Orders as b
ON a.Id=b.ClientId
GROUP BY a.client_name
order by TotalOrders desc
LIMIT 1

SQL Server Join tables

I want each student's name, last payment date only. means only day.
I know i won't help you at all giving this code:
But you could try to learn something from it.
SELECT S.Id, S.Name, F.max_date, F.FeeAmt
FROM tbl_student As S
INNER JOIN (
SELECT t.Id, MAX(t.Date) As max_date, t.FeeAmt FROM tbl_fees As t GROUP BY t.Id
) As F ON F.Id=S.Id
First we selected all users from tbl_student, and then we are joining fees, selecting max date and grouping by user. The result is last (date) fee per user.
Please try this query. I hope this should give you the expected output:
SELECT S.Name, T1.LastPaymentDate
FROM
(SELECT Id, Max([Date]) AS LastPaymentDate from tbl_fees GROUP BY Id) AS T1
INNER JOIN
tbl_student AS S
ON T1.Id = S.Id
SELECT S.name,SUB.LAST_DATE
FROM tbl_student S
JOIN (SELECT f.id AS ID,MAX(f.Date) AS LAST_DATE
FROM tbl_fees f
GROUP BY f.id) SUB
ON SUB.id = S.id

Mysql query select non-members

I have 2 tables:
Customers:
- ID
- NAME
Modulemembers:
- ID
- customer_id
- enabled
I use this to enable a function of my site for some customers.
I have a form where the admin of the site can add the module for a customer, so i need a query that looks for customers that are NOT member of the modulemembers table.
I made this:
SELECT customers.id,
customers.name
FROM customers,
modulemembers
WHERE customers_id != modulemembers.cust_id
ORDER BY customers.name
but it does not work. What am I doing wrong?
You can use NOT EXISTS in the WHERE clause to get the result:
SELECT c.id,
c.name
FROM customers c
WHERE not exists (select customer_id
from modulemembers m
where c.id = m.customer_id)
order by c.name
You can use a LEFT OUTER JOIN and filter based on NULLs. The query below will pull in all results from the customers table and the modulemembers table. If there is not a match in the modulemembers table then the custid will be NULL.
SELECT c.id, c.name
FROM customers c
LEFT OUTER JOIN modulemembers m ON c.customers_id = m.cust_id
WHERE m.custid IS NULL
ORDER BY c.name
Try something like this:
SELECT c.ID AS customerId,
c.NAME AS fullName,
m.ID AS memberId
FROM Customers AS c
LEFT JOIN Modulemembers AS m ON m.customer_id = c.ID
WHERE m.ID IS NULL;

HQL/SQL select top 10 records based on count

I have 2 tables:
CATEGORY (id)
POSTING (id, categoryId)
I am trying to write an HQL or SQL query to find top 10 Categories which have the most number of Postings.
Help is appreciated.
SQL query:
SELECT c.Id, sub.POSTINGCOUNT
FROM CATEGORY c where c.Id IN
(
SELECT TOP 10 p.categoryId
FROM POSTING p
GROUP BY p.categoryId
order by count(1) desc
)
HQL:
Session.CreateQuery("select c.Id
FROM CATEGORY c where c.Id IN
(
SELECT p.categoryId
FROM POSTING p
GROUP BY p.categoryId
order by count(1) desc
)").SetMaxResults(10).List();
http://sqlinthewild.co.za/index.php/2010/01/12/in-vs-inner-join/
In SQL you can do this:
SELECT c.Id, sub.POSTINGCOUNT
FROM CATEGORY c
INNER JOIN
(
SELECT p.categoryId, COUNT(id) AS 'POSTINGCOUNT'
FROM POSTING p
GROUP BY p.categoryId
) sub ON c.Id = sub.categoryId
ORDER BY POSTINGCOUNT DESC
LIMIT 10
SQL can be like :
SELECT c.* from CATEGORY c, (SELECT count(id) as postings_count,categoryId
FROM POSTING
GROUP BY categoryId ORDER BY postings_count
LIMIT 10) d where c.id=d.categoryId
This output can be mapped to the Category entity.
I know that is an old question, but i reached a satisfatory answer.
JPQL:
//the join clause is necessary, because you cannot use p.category in group by clause directly
#NamedQuery(name="Category.topN",
query="select c, count(p.id) as uses
from Posting p
join p.category c
group by c order by uses desc ")
Java:
List<Object[]> list = getEntityManager().createNamedQuery("Category.topN", Object[].class)
.setMaxResults(10)
.getResultList();
//here we must made a conversion, because the JPA cannot order using a non select field (used stream API, but you can do it in old way)
List<Category> cats = list.stream().map(oa -> (Category) oa[0]).collect(Collectors.toList());