Two records limit when the same column - mysql

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;

Related

How to select rows from two tables using MySQL?

I want to select information from two SQL tables within one query.
table1
id | postID | status | number | userID | active
1 | 1 | 100 | 100 | 3 | 1
2 | 7 | 50 | 25 | 5 | 1
3 | 3 | 75 | 50 | 3 | 1
table2
postID | reference | joint_date | userID | remove
1 | 100 | 100 | 3 | 1
2 | 50 | 25 | 5 | 1
3 | 50 | 50 | 3 | 0
Expected Output
postID | status | number | reference | joint_date
1 | 100 | 100 | 100 | 100
3 | 75 | 50 | 50 | 50
This is my try:
$userID = 12;
$active = 1;
$remove= 1;
$sql = "SELECT table1.status, table1.number, table2.reference, table2.joint_date
FROM table1
WHERE table1.active=:active AND table1.userID=:userID
INNER JOIN table2 ON table1.postID=table2.postID
WHERE table2.postID=:userID
AND table2.remove=:remove
ORDER BY table1.postID DESC";
$stmt = $this->pdo->prepare($sql);
$stmt->bindValue(":active", $active, PDO::PARAM_INT);
$stmt->bindValue(":userID", $userID, PDO::PARAM_INT);
$stmt->bindValue(":remove", $remove, PDO::PARAM_INT);
$stmt->execute();
What is wrong with my query?
What is wrong with my query?
The clauses/statements order are wrong
SELECT....FROM....WHERE....AND....AND....ORDER BY..
You can not have two WHERE condition in the same SELECT (do not take in consideration subqueries)
There is no way you can get the expected result based on the given static variables
Based on the data example you have two condition which will never be true at the same time.
AND t2.postID=3 --- > t2.remove is equal to 0 then you specify
AND t2.remove=1
You can use below example to properly filter based on your conditions:
SELECT t1.postID,
t1.status,
t1.`number`,
t2.reference,
t2.joint_date
FROM table1 t1
INNER JOIN table2 t2 ON t1.postID=t2.postID
WHERE t1.active=1
AND t1.userID=3
ORDER BY t1.postID ASC;
Result:
postID status number reference joint_date
1 100 100 100 100
3 75 50 50 50
Note. I removed both conditions table2.postID=:userID AND table2.remove=:remove
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=78b0f07c7d1dd1db1008e415fc005e85

How to use Mysql SUM with JOIN

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;

MySQL group by with MAX not working as expected?

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

SQL with specific LIMIT

I have the next example table:
id | user_id | data
-------------------
1 | 1 | 10
2 | 2 | 10
3 | 2 | 10
4 | 1 | 10
5 | 3 | 10
6 | 4 | 10
7 | 4 | 10
8 | 5 | 10
9 | 5 | 10
10 | 2 | 10
11 | 6 | 10
12 | 3 | 10
13 | 1 | 10
I need to create a SELECT query, that LIMITS my data. For example, I have a limit range (1, 3) (page number = 1, row count = 3). It should selects rows with first 3 unique user_id. And if there are some rows in the end of table with this first user_id's, they should be included to the result. LIMIT statement is bad for this query, because I can get more than 3 rows. Output for my limit should be:
id | user_id | data
-------------------
1 | 1 | 10
2 | 2 | 10
3 | 2 | 10
4 | 1 | 10
5 | 3 | 10
10 | 2 | 10
12 | 3 | 10
13 | 1 | 10
Can you help me to generate this query?
How about:
SELECT *
FROM table
WHERE user_id IN
(SELECT distinct(user_id) FROM table order by user_id LIMIT 3);
What about something like this?
SELECT * FROM table WHERE user_id BETWEEN (number) AND (number+row count)
I know it isn't working but you should be able to make it work ^^
The sample code below can be used for Oracle & Mysql. (use TOP for SQL Server & Sybase)
You get all the results from your table (t1) that match the top 3 user_id (t2) (check the MySQL manual for the limit function)
SELECT *
FROM exampletable t1
INNER JOIN (
SELECT DISTINCT user_id
FROM exampletable
ORDER BY user_id
LIMIT 0,3 -- this is the important part
) AS t2 ON t1.user_id = t2.user_id
ORDER BY id
For the next 3 id's change the limit 0,3 to limit 3,6.

Mysql Query group by

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...