I am trying to make a query to get some results:
I have a table with some data:
client | price
1 | 100
1 | 150
1 | 200
2 | 90
2 | 130
2 | 200
3 | 95
3 | 120
3 | 250
I would like with one query to select the results and order it by price and client and get them in this form, ordered by the best price of each clint:
2 | 90
2 | 130
2 | 200
3 | 95
3 | 120
3 | 250
1 | 100
1 | 150
1 | 200
SELECT tbl.client, ytbl.price
FROM (SELECT client, min(price) as mpr FROM yourtable group by client) tbl
JOIN yourtable ytbl ON ytbl.client=tbl.client
ORDER BY tbl.mpr ASC, tbl.client ASC, ytbl.price ASC
Something like that...
Related
I have 2 (MySQL) tables , exchange table can have 1--n rows in exchitems, when an exchange record has multiple rows, I would like to display the word "multi", but when there is only 1 row, I would like to display the row's details:
First table (exchange):
xid (PK) | cusid | xdate | xref | xtotal
1 | 1 | 2021-10-01 | 345667 | 500
2 | 1 | 2021-10-01 | 345668 | 200
3 | 1 | 2021-10-02 | 345669 | 450
4 | 1 | 2021-10-03 | 345670 | 1200
And the second table (exchitems):
chid (PK) | xid | cusid | xcur| xsell| xbuy
1 | 1 | 1 | USD | 300 | 0
2 | 1 | 1 | EUR | 0 | 400
3 | 2 | 1 | USD | 200 | 0
4 | 3 | 1 | EUR | 0 | 500
5 | 4 | 1 | EUR | 0 | 800
6 | 4 | 1 | USD | 300 | 0
The exchange table must have at least 1 row in exchtiems table, and this is what I would like to get:
xid | cusid | xdate | xref | xcur | xsell | xbuy | xtotal
1 | 1 | 2021-10-01 | 345667 | multi | 0 | 0 | 500
2 | 1 | 2021-10-01 | 345668 | USD | 200 | 0 | 200
3 | 1 | 2021-10-02 | 345669 | EUR | 0 | 500 | 450
4 | 1 | 2021-10-03 | 345670 | multi | 0 | 0 | 1200
Using the following query, i am able to get the all records, but I would like to limit the exchitems table to one row "any row" when there are multiple rows, the count is used to display the word "multi" when it is > 1:
SELECT a.xid,a.xdate,a.xref,a.xtotal,b.xcur,b.xsell,b.xbuy,
(SELECT COUNT(*) FROM exchitems c WHERE c.xid= a.xid) AS tRec
FROM (exchange a
INNER JOIN exchitems b ON a.xid= b.xid AND a.cusid= b.cusid)
WHERE a.cusid = 1
ORDER BY a.xdate DESC,a.xid DESC
I have tried many different queries but couldn't achieve what I want.
Any help is highly appreciated.
Untested, but this should work.
SELECT
a.xid,
a.cusid,
a.xdate,
a.xref,
-- if distinct currency in the group is > 1 then the word 'multi', else currency.
IF(COUNT(DISTINCT b.xcur) > 1, 'multi', b.xcur) AS `xcur`,
b.xsell,
b.xbuy,
a.xtotal
FROM exchange a
JOIN exchitems b ON a.xid = b.xid AND a.cusid = b.cusid
WHERE a.cusid = 1
GROUP BY xid -- will let you have exchange rows with groups of exchitems 1:n
ORDER BY a.xdate DESC, a.xid DESC
You can modify your current query to the following:
SELECT a.xid, a.cusid, a.xdate,
a.xref,
GROUP_CONCAT(b.xcur),
MIN(b.xsell),
MIN(b.xbuy),
MAX(a.xtotal)
FROM (exchange a
INNER JOIN exchitems b ON a.xid= b.xid AND a.cusid= b.cusid)
WHERE a.cusid = 1
GROUP BY a.xid,a.cusid,a.xdate,a.xref
ORDER BY a.xid;
The result will look like this:
xid
cusid
xdate
xref
GROUP_CONCAT(b.xcur)
MIN(b.xsell)
MIN(b.xbuy)
MAX(a.xtotal)
1
1
2021-10-01
345667
USD,EUR
0
0
500
2
1
2021-10-01
345668
USD
200
0
200
3
1
2021-10-02
345669
EUR
0
500
450
4
1
2021-10-03
345670
EUR,USD
0
0
1200
The part where I use MIN and MAX is according to your expected result. You may want to clarify which value to show there is you have multiple value. If I change that to GROUP_CONCAT:
SELECT a.xid, a.cusid, a.xdate,
a.xref,
GROUP_CONCAT(b.xcur),
GROUP_CONCAT(b.xsell),
GROUP_CONCAT(b.xbuy),
GROUP_CONCAT(a.xtotal)
FROM (exchange a
INNER JOIN exchitems b ON a.xid= b.xid AND a.cusid= b.cusid)
WHERE a.cusid = 1
GROUP BY a.xid,a.cusid,a.xdate,a.xref
ORDER BY a.xid;
Then you'll see a more elaborate result:
xid
cusid
xdate
xref
GROUP_CONCAT(b.xcur)
GROUP_CONCAT(b.xsell)
GROUP_CONCAT(b.xbuy)
GROUP_CONCAT(a.xtotal)
1
1
2021-10-01
345667
USD,EUR
300,0
0,400
500,500
2
1
2021-10-01
345668
USD
200
0
200
3
1
2021-10-02
345669
EUR
0
500
450
4
1
2021-10-03
345670
EUR,USD
0,300
800,0
1200,1200
To make the xcur value show multi, you probably can do something like:
SELECT a.xid, a.cusid, a.xdate,
CASE WHEN COUNT(b.xcur) > 1 THEN 'multi' ELSE MAX(b.xcur) END AS xcur,
MIN(b.xsell),
MIN(b.xbuy),
MAX(a.xtotal)
FROM (exchange a
INNER JOIN exchitems b ON a.xid= b.xid AND a.cusid= b.cusid)
WHERE a.cusid = 1
GROUP BY a.xid,a.cusid,a.xdate,a.xref
ORDER BY a.xid;
Demo fiddle
I have the following tables:
purchase_tbl
id | productId | purchaseQuantity
---+-----------+-----------------
1 | 1 | 30
2 | 2 | 30
3 | 1 | 10
4 | 2 | 10
sale_tbl
id | productId | saleQuantity
---+-----------+-------------
1 | 1 | 10
2 | 2 | 10
3 | 1 | 10
4 | 2 | 10
5 | 1 | 10
6 | 2 | 10
I need to get the output as this one:
productId | totalPurchasedQuantity| totalSaleQuantity
----------+-----------------------+------------------
1 | 40 | 30
2 | 40 | 30
I'm using this query and how to get the desired result?
SELECT purchase_tbl.productId
, SUM(purchase_tbl.purchaseQuantity) AS totalPurchaseQuantity
, SUM(sale_tbl.saleQuantity) AS totalSaleQuantity
FROM purchase_tbl
JOIN sale_tbl
ON purchase_tbl.productId = sale_tbl.productId
GROUP BY purchase_tbl.productId
Current output
productId | totalPurchaseQuantity | totalSaleQuantity
----------+-----------------------+------------------
1 | 120 | 60
2 | 120 | 60
You better group then in separate query, as table have multiple records for each product, which getting cross product.
SELECT purchase.productId, totalPurchaseQuantity, totalSaleQuantity
FROM
(SELECT purchase_tbl.productId
, SUM(purchase_tbl.purchaseQuantity) AS totalPurchaseQuantity
FROM purchase_tbl
GROUP BY purchase_tbl.productId) purchase
INNER JOIN
(SELECT sale_tbl.productId
, SUM(sale_tbl.saleQuantity) AS totalSaleQuantity
FROM sale_tbl
GROUP BY sale_tbl.productId
) sale ON sale.productId= purchase.productId;
To obtain your expected result you have to do the aggregation on the individual table before joining them. Your query with be like:
SELECT A.productId, A.totalpurchaseQuantity, B.totalsaleQuantity
FROM
(SELECT productId, SUM(purchaseQuantity)
totalpurchaseQuantity FROM purchase_tbl
GROUP BY productId) A JOIN
(SELECT productId, SUM(saleQuantity)
totalsaleQuantity FROM sale_tbl
GROUP BY productId) B ON
A.productId=B.productId;
Hi I have a table with 4 columns. the table is as below
sampleId totalAmount discount netAmount
1 120 40 80
2 200 50 150
3 400 100 300
Now i want the totals summary row at the bottom of the table. Please look at the image file below. how can i achieve this?
You can use UNION ALL as below
select cast(sampleId as char(10)) as sampleId, totalAmount,discount, netAmount
from tab
union all
select 'Total', sum(totalAmount),sum(discount), sum(netAmount)
from tab
SqlFiddle Demo
1st column is converted to varchar becouse you want to Total word atthe bottom. Columns types in UNION must be the same type.
You may do union all
select * from tablename
union all
select 'Totals' as sampleId,
sum(totalAmount) as totalAmount,
sum(discount) as discount,
sum(netAmount) as netAmount
from tablename
Here is a demo
mysql> select * from test ;
+------+--------+----------+-----------+
| id | amount | discount | net_total |
+------+--------+----------+-----------+
| 1 | 120 | 40 | 80 |
| 2 | 200 | 50 | 150 |
| 3 | 500 | 100 | 300 |
+------+--------+----------+-----------+
3 rows in set (0.00 sec)
mysql> select * from test union all select 'Totals' as id,sum(amount) as amount,sum(discount) as discount,sum(net_total) as net_total from test ;
+--------+--------+----------+-----------+
| id | amount | discount | net_total |
+--------+--------+----------+-----------+
| 1 | 120 | 40 | 80 |
| 2 | 200 | 50 | 150 |
| 3 | 500 | 100 | 300 |
| Totals | 820 | 190 | 530 |
+--------+--------+----------+-----------+
SELECT
IFNULL(sampleId,"Total") as sampleId, SUM(totalAmount), SUM(discount), SUM(netAmount)
FROM tablename
GROUP BY sampleId WITH ROLLUP;
Try to use group by modifiers :
select Coalesce(sampleId, 'Total') `sampleId` , sum(totalAmount),sum(discount),sum(netAmount)
from t
group by sampleId with rollup
SQLFiddle : http://sqlfiddle.com/#!9/f1826/11
Here is a documentation on ROLLUP : https://dev.mysql.com/doc/refman/5.0/en/group-by-modifiers.html
I have column:
id | id_contract | price
I'd like to select all with the limit 2 the cheapest offer from one contract.
I use kochana ORM.
Thanks.
For example
1 | 1 | 100 *
2 | 1 | 500
3 | 1 | 300 *
4 | 1 | 900
5 | 2 | 1000
6 | 2 | 100 *
7 | 2 | 200 *
8 | 3 | 10000 *
This is what I want to select.
You can do this in MySQL with the following query:
select t.*
from table t
where (select count(*)
from table t2
where t2.id_contract = t.id_contract and
t2.price <= t.price
) <= 2;
I have a table:
ID | User | Amount
1 | 1 | 50
2 | 1 | 80
3 | 2 | 80
4 | 2 | 100
5 | 1 | 90
6 | 1 | 120
7 | 2 | 120
8 | 1 | 150
9 | 2 | 300
I do a query:
SELECT * FROM TABLE ORDER BY amount DESC group by userid
I'm getting this:
ID | User | Amount
1 | 1 | 50
2 | 1 | 80
But I was expecting:
ID | User | Amount
9 | 2 | 300
8 | 1 | 150
What is wrong with my sql?
When grouping you have to use aggregate functions like max() for all columns that are not grouped by
select t.*
from table t
inner join
(
SELECT userid, max(amount) as total
FROM TABLE
group by userid
) x on x.userid = t.userid and x.total = t.amount
ORDER BY t.amount DESC
Another solution.Check SQL Fiddle
Using FIND_IN_SET clause
SELECT
ua.*
FROM user_amount ua
WHERE FIND_IN_SET(ua.amount,(SELECT
MAX(ua1.amount)
FROM user_amount ua1
WHERE ua1.user = ua.user)) > 0
ORDER BY amount desc;
Using IN clause
SELECT
ua.*
FROM user_amount ua
WHERE ua.amount IN (SELECT
MAX(ua1.amount)
FROM user_amount ua1
WHERE ua1.user = ua.user)
ORDER BY amount desc