GROUB BY in MySQL JOIN query - mysql

There is two table. First one which stores fee per user
+----+----+----+
| id |uid |fee |
+----+----+----+
| 1 |P001|100 |
+----+----+----+
| 2 |P002|200 |
+----+----+----+
| 3 |P003|250 |
+----+----+----+
| 4 |P004|100 |
+----+----+----+
| 5 |P001|200 |
+----+----+----+
| 6 |P002|200 |
+----+----+----+
| 7 |P003|250 |
+----+----+----+
| 8 |P004|100 |
+----+----+----+
second one stores user classification
+----+-----+
|uid |class|
+----+-----+
|P001| 1 |
+----+-----+
|P002| 1 |
+----+-----+
|P003| 2 |
+----+-----+
|P004| 3 |
+----+-----+
I want to show their sum grouped by class as following
1 - 700
2 - 500
3 - 200
How should I write this SQL query? Thanks in advance.

Suppose first table tab1 and second1 is tab2
select t2.class,sum(t1.fee) from tab2 t2 inner join tab1 t1 on t2.uid=t1.uid
group by t2.class

Try this
SELECT a.class, SUM(b.fee)
FROM user_classification a
INNER JOIN user_fees b
ON a.uid = b.uid
GROUP BY a.class
ORDER BY a.class ASC

Try this:
SELECT class, SUM(fee)
FROM table1 t1
LEFT JOIN table2 t2
ON t1.uid = t2.uid
GROUP BY class

SELECT COUNT(*) AS Expr28, SInv_D.fTransUnitPrice AS fTransUnitPrice, SInv_D.fExtended AS Expr2, SInv_D.fTransQty * SInv_D.fTransUnitPrice AS fTransUnitPrice,
SInv.cMode AS cMode, SInv.cInvoicNum AS cInvoicNum, SInv.dOperaDate AS dOperaDate, SInv_D.cMode AS Expr9, SInv_D.cInvoicNum AS Expr10,
SInv_D.cItCode AS cItCode, SInv_D.cItName AS cItName, SInv_D.cTransUnit AS cTransUnit, SUM(SInv_D.fTransQty) AS fTransQty, SInv.cMode AS Expr4,
SInv.cInvoicNum AS Expr16, SInv_D.cItCode AS Expr15, SInv_D.fTransUnitPrice AS Expr19, SInv.dIssueDate AS Expr20, WareDef.cCode AS Expr21,
WareDef.cName1 AS Expr22, item.cUnitR AS Expr24, item.cName1 AS Expr25, item.fCostSTDR AS Expr26, SInv.cWare1 AS Expr27, item.cCode AS cCode, I.Expr999,
I.cItCode AS Expr1
FROM SInv LEFT OUTER JOIN
WareDef ON SInv.cWare1 = WareDef.cCode LEFT OUTER JOIN
SInv_D ON SInv.cInvoicNum = SInv_D.cInvoicNum AND SInv.dIssueDate = SInv_D.dIssueDate LEFT OUTER JOIN
item ON SInv_D.cItCode = item.cCode INNER JOIN
(SELECT SUM(fTransQty) AS Expr999, cItCode
FROM dbo.sinv_D
GROUP BY sinv_D.cItCode) I ON I.cItCode = SInv_D.cItCode
WHERE (SInv.dIssueDate BETWEEN 20130102 AND 20130109) AND (SInv.cWare1 = '003') AND (SInv.cMode = '122') AND (SInv_D.cMode = '122')
GROUP BY SInv_D.cItCode, SInv_D.fTransUnitPrice, SInv_D.fExtended, SInv_D.fTransQty, SInv.cMode, SInv.cInvoicNum, SInv.dOperaDate, SInv_D.cMode, SInv_D.cInvoicNum,
SInv_D.cItName, SInv_D.cTransUnit, SInv.dIssueDate, WareDef.cCode, WareDef.cName1, item.cUnitR, item.cName1, item.fCostSTDR, SInv.cWare1, item.cCode,
I.Expr999, I.cItCode

Related

MySQL joining table into query which has no refference with others

I would like to make a query from muliple prestashop tables to be able to import it to another database. The problem is that the third table has no refference to the other two and couldn't figure out how I can join them together.
To simplify things lets say the 3 table looking like this:
Table1 Table2 Table3
ID ID | Table1 ID ID
------ -------------- ------
1 11 | 1 12
2 22 | 1 13
3 44 | 2
55 | 2
66 | 3
77 | 3
And I would like this result:
firstID | secondID | thirdID
1 | 11 | 12
1 | 22 | 12
1 | 11 | 13
1 | 22 | 13
2 | 44 | 12
2 | 55 | 12
2 | 44 | 13
2 | 55 | 13
3 | 66 | 12
3 | 77 | 12
3 | 66 | 13
3 | 77 | 13
Or in words, I would like to assign everery Table3 ID to every Table2 ID and also display Table2's refference to Table1 aka Table1 ID
When I query Table1 and Table2 I usually do it like this:
SELECT p.`id` AS `firstID`, pa.`id` AS `secondID`
FROM `Table1` p
LEFT JOIN `Table2` pa ON (p.`id` = pa.`id`)
GROUP BY pa.`id`
ORDER BY p.`id`
But I wasn't able join the third table in so it would produce the desired outcome.
How can I achieve the above mentioned result?
You are looking for cross join with inner join. Try :
Select
a.ID, b.ID, c.ID
from
Table1 a Inner Join
Table2 b on a.ID = b.Table1_ID
Cross Join
Table3 c
This will fetch table1 and table2 based on ID and table3 will be cross joined with result.
More about cross join can be found here
EDIT: Renamed table ids to match OPs table structures.
SELECT t1.`ID` AS `firstID`, t2.`ID` AS `secondID`, t3.`ID` AS `thirdID`
FROM `Table1` t1
LEFT JOIN `Table2` t2 ON (t1.`ID` = t2.`Table1 ID`)
LEFT JOIN `Table3` t3 ON 1
ORDER BY t1.`ID`, t3.`ID`
This gives same result as you expect.
SELECT t1.`ID` AS `firstID`, t2.`ID` AS `secondID`, t3.`ID` AS `thirdID`
FROM `Table3` t3, `Table1` t1
LEFT JOIN `Table2` t2 ON (t1.`ID` = t2.`Table1 ID`)
ORDER BY t1.`ID`, t3.`ID`

Select last record of each person

I have the following tables
tbl_investors
id | first_name | last_name |
---------------------------------------
1 | Jon | Cold |
2 | Rob | Ark |
3 | Rickon | Bolt |
tbl_investors_ledger
id | investor_id | amount |
------------------------------------
1 | 1 | 500 |
2 | 2 | 200 |
3 | 2 | 250 |
4 | 2 | 300 |
5 | 3 | 10 |
6 | 1 | 550 |
7 | 3 | 20 |
I just want to return all investors with their latest amount. Ex, Jon Cold with 550, Rob Ark 300 and Rickon Bolt 20, alphabetically with their last name.
I have an existing query but it will not return the latest amount of the investor. Can someone help me what i'm doing wrong?
SELECT t1.*, t2.*
FROM ".tbl_investors." t1
LEFT JOIN ".tbl_investors_ledger." t2
ON t1.id = t2.investor_id
LEFT JOIN (SELECT t.investor_id, max(t.id) as tid
FROM ".tbl_investors_ledger." t ) tt
ON tt.investor_id = t2.investor_id AND tt.tid = t2.id
GROUP BY t2.investor_id
ORDER BY t1.last_name
You can use GROUP_CONCAT and SUBSTRING_INDEX together
SELECT I.*
, SUBSTRING_INDEX(GROUP_CONCAT(L.amount ORDER BY L.id DESC), ',', 1) AS LastAmount
FROM tbl_investors AS I
LEFT JOIN tbl_investors_ledgers AS L
ON L.investor_id = I.id
GROUP BY I.id
ORDER BY I.last_name
Here a demo from SQLFiddle, many thanks to #zakhefron :)
Try this;)
SELECT t1.*, t2.*
FROM tbl_investors t1
LEFT JOIN tbl_investors_ledger t2
ON t1.id = t2.investor_id
INNER JOIN (
SELECT t.investor_id, max(t.id) as tid
FROM tbl_investors_ledger t GROUP BY t.investor_id) tt
ON tt.investor_id = t2.investor_id AND tt.tid = t2.id
ORDER BY t1.last_name
SQLFiddle DEMO
And check related OP Retrieving the last record in each group and this blog How to select the first/least/max row per group in SQL, you can find more solutions for your question.

MySQL - Count only if the last associated_statut = 2

Alright, I have those columns on MySQL :
id
id_conv
associated_statut
The associated_statut is a number between 1 and 7.
What I want to do is to count only the id_conv if the LAST associated_statut for this id_conv is 2 for example.
Example :
-----------------------------------------------
| id | id_conv | associated_statut |
-----------------------------------------------
| 1 | 15 | 1 |
| 2 | 15 | 2 |
| 3 | 15 | 2 |
| 4 | 15 | 4 |
| 5 | 15 | 2 |
| 6 | 15 | 3 |
The id_conv would NOT be counted if I want the associated_statut = 2, because the last associated_statut for this id_conv is 3.
I already tried this query :
SELECT COUNT(DISTINCT id_conv) FROM MyTable WHERE associated_statut = 2
But this doesn't returns what I want.
Is there a way to do this in SQL ?
Thanks.
Maybe, this will work for you:
SELECT count(t1.id) FROM mytable t1
INNER JOIN (SELECT id_conv, MAX(id) id FROM foo GROUP BY id_conv) t2
ON t1.id = t2.id
WHERE t1.associated_statut = 2
SELECT COUNT(sub1.id_conv) FROM MyTable
INNER JOIN
(
SELECT DISTINCT id, FIRST(associated_statut ORDER BY id DESC)
group by id_conv
recent FROM MyTable
) sub1 ON sub1.id = MyTable.id
WHERE sub1.recent_associated_statut = 2
We can do same thing without sub query. It will take less time when you have more data.
SELECT count(t1.id) FROM
mytable t1
LEFT JOIN
mytable t2
ON t1.id_conv = t2.id_conv
AND t1.id < t2.id
WHERE t2.id IS NULL
AND t1.associated_statut = 2;

Get min price id without inner select

I have a table called a with this data:
+-----+-----------+-------+
| id | parent_id | price |
+-----+-----------+-------+
| 1 | 1 | 100 |
| 2 | 1 | 200 |
| 3 | 1 | 99 |
| 4 | 2 | 1000 |
| 5 | 2 | 999 |
+-----+-----------+-------+
I want to get the id of min pirce for each parent_id.
There is any way to get this result without subquery?
+-----+-----------+-------+
| id | parent_id | price |
+-----+-----------+-------+
| 3 | 1 | 99 |
| 5 | 2 | 999 |
+-----+-----------+-------+
SELECT D1.id, D1.parent_id, D1.price
FROM Data D1
LEFT JOIN Data D2 on D2.price < D1.price AND D1.parent_id = D2.parent_id
WHERE D2.id IS NULL
Here is a shot at how to do it without subqueries. I haven't tested, let me know if it works!
SELECT t.id, t.parent_id, t.price
FROM table t
LEFT JOIN table t2
ON (t.parent_id = t2.parent_id AND t.price > t2.price)
GROUP BY t.id, t.parent_id, t.price
HAVING COUNT(*) = 1 AND max(t2.price) is null
ORDER BY t.parent_id, t.price desc;
Try this:
SELECT T1.id,T2.parent_id,T2.price FROM
(SELECT id,price
FROM TableName) T1
INNER JOIN
(
SELECT parent_id,MIN(price) as price
FROM TableName
GROUP BY parent_id) T2 ON T1.price=T2.price
See result in SQL Fiddle.
Try group by,
SELECT parent_id,min(price)
FROM TableName
GROUP BY parent_id
You can do this with a LEFT JOIN
SELECT a.id, a.parent_id, a.price
FROM a
LEFT JOIN a AS b ON b.price < a.price AND b.parent_id = a.parent_id
WHERE b.id IS NULL
Find the results at this fiddle:
http://sqlfiddle.com/#!2/09c888/10
You can try this without using any join or subquery you will surely get the desired result.
SELECT TOP 2 FROM a ORDER BY price

count value for each unique id

I have a table
id value
1 a
2 a
3 b
4 b
5 b
6 c
My id is primary.
I have total 2 a , 3 b and 1 c. So I want to count total repeat value in each primary id which matches on it
I want this format
id value_count
1 2
2 2
3 3
4 3
5 3
6 1
Try this query:
SELECT a.id, b.valueCnt
FROM tableA a
INNER JOIN (SELECT a.value, COUNT(a.value) valueCnt
FROM tableA a GROUP BY a.value) AS B ON a.value = b.value;
Check the SQL FIDDLE DEMO
OUTPUT
| ID | VALUECNT |
|----|----------|
| 1 | 2 |
| 2 | 2 |
| 3 | 3 |
| 4 | 3 |
| 5 | 3 |
| 6 | 1 |
Try This
select id, value_count from tablename as a1
join (select count(*) as value_count, value from tablename group by value) as a2
on a1.value= a2.value
I suggest you use a subselect without any joins:
SELECT
a.id,(SELECT COUNT(*) FROM tableA WHERE value = a.value) as valueCnt
FROM tableA a
Fiddle Demo
You need to use subquery.
SELECT table.id , x.value_count
FROM table
INNER JOIN
(SELECT t1.value, count(t1.id) as value_count
FROM table t1
Group by t1.value
) x on x.value = table.value