mysql query with double join - sql

I have 3 tables, but I can only get to join another table count. See below.
The one below works like a charm, but I need to add another "count" from another table.
there is a 3rd table called "ci_nomatch" and contains a reference to ci_address_book.reference
which could have multiple entries (many on many) but I only need the count of that table.
so if ci_address_book would have an entries called "item1","item 2","item3"
and ci_nomatch would have "1,item1,user1","2,item1,user4"
I would like to have returned "2" for Item1 on the query.
Any ideas? I tried another join, but it tells me that the reference does not exist, while it does!
SELECT c.*, IFNULL(p.total, 0) AS matchcount
FROM ci_address_book c
LEFT JOIN (
SELECT addressbook_id, COUNT(match_id) AS total
FROM ci_matched_sanctions
GROUP BY addressbook_id
) AS p
ON c.id=p.addressbook_id
ORDER BY matchcount DESC
LIMIT 0,15

You could subquery it directly in the select
SELECT c.*, IFNULL(p.total, 0) AS matchcount,
(SELECT COUNT(*) FROM ci_nomatch n on n.reference = c.reference) AS othercount
FROM ci_address_book c
LEFT JOIN (
SELECT addressbook_id, COUNT(match_id) AS total
FROM ci_matched_sanctions
GROUP BY addressbook_id
) AS p
ON c.id=p.addressbook_id
ORDER BY matchcount DESC
LIMIT 0,15
#updated for comment. Including an extra column "(matchcount - othercount) AS deducted" would be best done by sub-querying.
SELECT *, matchcount - othercount AS deducted
FROM
(
SELECT c.* , IFNULL( p.total, 0 ) AS matchcount, (
SELECT COUNT( * ) FROM ci_falsepositives n
WHERE n.addressbook_id = c.reference ) AS othercount
FROM ci_address_book c
LEFT JOIN (
SELECT addressbook_id, COUNT( match_id ) AS total
FROM ci_matched_sanctions GROUP BY addressbook_id ) AS p
ON c.id = p.addressbook_id ORDER BY matchcount DESC LIMIT 0 , 15
) S

Related

JOIN 2 tables ORDER BY SUM value

I have 2 tables: 1st is comment, 2nd is rating
SELECT * FROM comment_table a
INNER JOIN (SELECT comment_id, SUM(rating_value) AS total_rating FROM rating_table GROUP BY comment_id) b
ON a.comment_id = b.comment_id
ORDER BY b.total_rating DESC
I tried the above SQL but doesn't work!
Object is to display a list of comments order by rating points of each comments.
SELECT s.* FROM (
SELECT * FROM comment_table a
INNER JOIN (SELECT comment_id, SUM(rating_value) AS total_rating FROM rating_table GROUP BY comment_id) b
ON a.comment_id = b.comment_id
) AS s
ORDER BY s.total_rating DESC
Nest it inside an another select. It will then output the data in the correct order.

Can I sum the count of two columns from two different tables?

I'm trying to add together the counts of two different tables and group them by the same variable
Here is what I have so far:
SELECT a.storenumber,
Count (howmanytotal) AS total_counts_store
FROM (
SELECT month_counts.howmany,
new_counts.howmany) AS howmanytotal
from (
SELECT a.storenumber,
count (b.riid_) AS howmany
FROM $b$ b
INNER JOIN $a$ a
ON b.riid_=a.riid_
GROUP BY a.storenumber) month_counts
FROM (
SELECT a.storenumber,
count (c.riid_) AS howmany
FROM $c$ c
INNER JOIN $a$ a
ON c.riid_=a.riid_
GROUP BY a.storenumber) new_counts
ON month_counts.storenumber = new_counts.storenumber) theend
where I'm at now:
SELECT howmanytotal AS total_counts_store
FROM (
SELECT Count (howmany) AS howmanytotal)
FROM (
SELECT month_counts.howmany,
new_counts.howmany)
FROM (
SELECT a.storenumber,
count (b.riid_) AS howmany
FROM $b$ b
inner join $a$ a
ON b.riid_=a.riid_
GROUP BY a.storenumber) month_counts
UNION
(
SELECT count (c.riid_) AS howmany
FROM $c$ c
inner join $a$ a
ON c.riid_=a.riid_
GROUP BY a.storenumber) new_counts
ON month_counts.storenumber = new_counts.storenumber) ORDER BY $a$.storenumber
Getting this error: Error: java.sql.SQLSyntaxErrorException: ORA-00923: FROM keyword not found where expected
Please correct SELECT statement:
Join the subqueries:
select
storenumber,
month_counts.howmany as month_count,
new_counts.howmany as new_count,
month_counts.howmany + new_counts.howmany as total_count
from (...) month_counts
join (...) new_counts using (storenumber)
order by storenumber;
If it is possible for a storenumber to be missing from one of the subquery results, then outer join and use COALESCE or NVL to deal with the nulls. Here is a query with a full outer join, which is not available in MySQL, but in Oracle and many other DBMS.
select
storenumber,
month_counts.howmany as month_count,
new_counts.howmany as new_count,
nvl(month_counts.howmany, 0) + nvl(new_counts.howmany, 0) as total_count
from (...) month_counts
full outer join (...) new_counts using (storenumber)
order by storenumber;
Ending up using sum and union to complete. Thank you for your help.
SELECT storenumber,
SUM(howmany) AS howmanytotal
FROM (SELECT a.storenumber,
Count (b.riid_) AS howmany
FROM $b$ b
inner join $a$ a
ON b.riid_ = a.riid_
GROUP BY a.storenumber
UNION
SELECT a.storenumber,
Count (c.riid_) AS howmany
FROM $c$ c
inner join $a$ a
ON c.riid_ = a.riid_
GROUP BY a.storenumber)
GROUP BY storenumber
ORDER BY storenumber
This gave me a list of store ids and how many active subscribers we have at each store (taken from two separate tables)

Get the second last record in a date column within a inner join

I need to pull the second last record in a date column called OrderDate. However, I need to bring only one date (I am making the search into a table with all the purchases orders, dates and costs, in which a have to bring only the second last and its cost). The way its query is written today (and working) is pulling me the the newest date.
select distinct
a.PurchaseNum, a.ItemID, a.SupplierNum, a.Location, a.OrderDate, a.Cost
from
PurchaseOrder a
inner join
(select
l.SupplierNum, l.ItemID, l.Location, maxdate = max(l.OrderDate)
from
PurchaseOrder l
where
l.Cost <> 0
group by
l.SupplierNum, l.itemid, l.Location) l on a.SupplierNum = l.SupplierNumand a.itemid = l.itemid
and l.Location = a.Location
and a.OrderDate = l.maxdate
I have tried to use lag(), offset (but with limitations once is within a join, forcing me to use the order by and include the dateOrder column which is not what I want because we need only one date)
A bit of context: I have a report in which I need to show the last and second last cost of a purchase order for each supplier. Bring the last cost of an order is easy, the problem is go back to the second last... and it is where I am stuck right now.
Any thought?
If I'm understanding you correctly, here's one option using row_number to return the 2 highest orderdate records:
select *
from (
select *,
row_number() over (partition by SupplierNum, ItemID, Location
order by OrderDate desc) rn
from PurchaseOrder
where cost <> 0
) t
where rn <= 2
Inner query does order by desc and outside query does order by asc.
select distinct top 1 a.*
from PurchaseOrder a
inner join
(
select Top 2 l.*
from PurchaseOrder l
where
l.Cost <> 0
group by l.SupplierNum, l.itemid, l.Location order by orderdate desc) l
on a.SupplierNum= l.SupplierNumand a.itemid = l.itemid and l.Location=a.Location and a.OrderDate = l.Orderdate
order by a.orderdate
or
SELECT TOP 1 * FROM (SELECT * FROM PurchaseOrder a
EXCEPT SELECT TOP (SELECT (COUNT(*)-2) FROM PurchaseOrder a where
l.Cost <> 0
group by l.SupplierNum, l.itemid, l.Location) * FROM PurchaseOrder) A
or
SELECT *
FROM PurchaseOrder a
WHERE OrderDate = ( SELECT MAX(OrderDate)
FROM PurchaseOrder
WHERE Orderdate < ( SELECT MAX(OrderDate)
FROM PurchaseOrder l where
l.Cost <> 0
group by l.SupplierNum, l.itemid, l.Location
)
) ;
or
SELECT TOP (1) *
FROM PurchaseOrder
WHERE OrderDate < ( SELECT MAX(OrderDate)
FROM PurchaseOrder where ....
)
ORDER BY OrderDate DESC ;

Row value from another table

I have a table that is having 2 duplicate rows (total of 3 rows), so I used the code below to get the duplicate value in the column
SELECT CustNo, COUNT(*) TotalCount
FROM Rental
GROUP BY CustNo
HAVING COUNT(*) > 1
ORDER BY COUNT(*) DESC
So once I get the repeated value, I need to get the CustNo derived as duplicate from the customer table. How do I go about taking this value and using it in the select statment all in the same query.
I also have the select statement prepared like this.
Select * from Customer where CustNo = 'T0002';
Thanks.
Select * from Customer
where CustNo IN
(
SELECT CustNo
FROM Rental
GROUP BY CustNo
HAVING COUNT(*) > 1
)
You can use join:
SELECT c.*
FROM (SELECT CustNo, COUNT(*) TotalCount
FROM Rental
GROUP BY CustNo
HAVING COUNT(*) > 1
) cc JOIN
Customer c
on cc.CustNo = c.CustNo;
Select C.* from Customer C RIGHT JOIN (
SELECT CustNo
FROM Rental
GROUP BY CustNo
HAVING COUNT(*) > 1) D
ON C.CustNo = D.CustNo
You can also try this,
With tblDups as(
select CustNo,count(CustNo) as TotalCount from a_rental
Group by CustNo
Having count(CustNo) >1)
select b.* from a_rental b
inner join tblDups a on a.CustNo = b.Custno

Help with SQL QUERY OF JOIN+COUNT+MAX

I need a help constructung an sql query for mysql database. 2 Table as follows:
tblcities (id,name)
tblmembers(id,name,city_id)
Now I want to retrieve the 'city' details that has maximum number of 'members'.
Regards
SELECT tblcities.id, tblcities.name, COUNT(tblmembers.id) AS member_count
FROM tblcities
LEFT JOIN tblmembers ON tblcities.id = tblmembers.city_id
GROUP BY tblcities.id
ORDER BY member_count DESC
LIMIT 1
Basically: retrieve all cities and count how many members each has, sort by that member count in descending order, making the highest count first - then show only that first city.
Terrible, but that's a way of doing it:
SELECT * FROM tblcities WHERE id IN (
SELECT city_id
FROM tblMembers
GROUP BY city_id
HAVING COUNT(*) = (
SELECT MAX(TOTAL)
FROM (
SELECT COUNT(*) AS TOTAL
FROM tblMembers
GROUP BY city_id
) AS AUX
)
)
That way, if there is a tie, still you'll get all cities with the maximum number of members...
Select ...
From tblCities As C
Join (
Select city_id, Count(*) As MemberCount
From tblMembers
Order By Count(*) Desc
Limit 1
) As MostMembers
On MostMembers.city_id = C.id
select top 1 c.id, c.name, count(*)
from tblcities c, tblmembers m
where c.id = m.city_id
group by c.id, c.name
order by count(*) desc