Is there a way to get unique rows for same value - php

Hello and sorry if this questions isn't good formatted, here's my problem:
for simplicity let's say i have a table with products
-----------------------
| id| age |price|name|
----------------------|
| 0 | 0 | 50 | x |
| 1 | 1 | 51 | x |
| 2 | 2 | 52 | x |
| 3 | 3 | 53 | x |
| 4 | 4 | 54 | x |
| 5 | 5 | 55 | x |
| 6 | 6 | 56 | x |
| 7 | 7 | 57 | x |
| 8 | 8 | 58 | x |
-----------------------
I want to get the price for all products of age 0 and 1 with
select price from products where name='x' and(age=0 or age=1)
and it works returning two rows but when the age is the same logically it returns one row and that's my problem how to get it to return again all the rows i want or if something other is wrong with my logic, thank you in advance

One way to achieve this is to build a derived table of the ages that you want to query against and then JOIN that to the products table. Note that you need to use UNION ALL in the derived table to maintain duplicates. Additional values can be searched by adding another UNION ALL SELECT n to the derived table for each value:
SELECT p.price
FROM (SELECT 0 AS age
UNION ALL
SELECT 0) ages
JOIN products p ON p.age = ages.age
WHERE p.name = 'x'
Output:
price
50
50
Demo on dbfiddle

Related

how to achieve permutation and combination from a single table based on cost using mysql and php?

I have a table where
sr_id is primary_key with auto increment
skuid is identification number for each product &
price is cost for that product
Table name: sample_records
sr_id | skuid | price
----------------------
1 | SKOO1 | 12
2 | SKOO2 | 7
3 | SKOO3 | 56
4 | SKOO4 | 3
5 | SKOO5 | 23
6 | SKOO6 | 50
7 | SKOO7 | 34
8 | SKOO8 | 5
9 | SKOO9 | 23
10 | SKO10 | 56
11 | SKO11 | 101
12 | SKO12 | 4
13 | SKO13 | 23
14 | SKO14 | 56
Now I need a combination based on price. Let's say I am giving the cost as 500. Below is the expected result:
ROW | skuid | quantity | cost |
---------------------------------------------
1 | SKOO1 | 41 | 492
---------------------------------------------
2 | SKOO1,SKOO2 | 41,1 | 497
---------------------------------------------
3 | SKOO1,SKOO2 | 40,2 | 494
---------------------------------------------
4 | SKOO1,SKOO2,SKOO8 | 40,2 1 | 499
---------------------------------------------
.
.
.
The result should get all combinations..
Note:-
quantity and cost are dynamically added columns.
Please help me to get a feasible solution.
You can use a recursive CTE to get the permutations:
with recursive cte as (
select cast(skuid as char(1000)) skuids, price, skuid as max_skuid
from sample
where price < 50
union all
select concat_ws(',', cte.skuids, s.skuid), cte.price + s.price, s.skuid
from cte join
sample s
on s.skuid > cte.max_skuid and
s.price + cte.price < 50
)
select *
from cte;
Here is a db<>fiddle.

Use of MIN() to select just one record per code (MySQL) [duplicate]

This question already has answers here:
SQL Group By and min (MySQL)
(3 answers)
Closed 6 years ago.
[Foreword for the compulsives -1] I know this question has been answered, at least, a billion times, but the problem is that I can't model those answers to what I wanna obtain. I'm not an SQL expert, that's sure; I'm confident just with the classical commands like SELECT, UPDATE, DELETE, ecc. so I'm gonna thank anyone who will like to help me.
Said that, let's suppose I have a table like this one:
|----|--------|------------|----|----------|---------|---------|------|
| id | code | category | mq | weight | weave | price | show |
|----|--------|------------|----|----------|---------|---------|------|
| 1 | DT450R | carbon | 1 | 450 | plain | 90 | 1 |
| 2 | DT450R | carbon | 2 | 450 | plain | 40 | 1 |
| 3 | DT450R | carbon | 5 | 450 | plain | 75 | 1 |
| 4 | ZX300R | carbon | 1 | 300 | plain | 12 | 0 |
| 5 | ZX300R | carbon | 15 | 300 | plain | 128 | 1 |
| 6 | ZX300R | carbon | 30 | 300 | plain | 92 | 1 |
| 7 | PP120Q | carbon | 3 | 120 | twill | 28 | 1 |
| 8 | PP120Q | carbon | 7 | 120 | twill | 65 | 1 |
| 9 | PP120Q | carbon | 9 | 120 | twill | 49 | 1 |
What I would like my query to do is to select, for each code, just the row with the minimum price:
| 2 | DT450R | carbon | 2 | 450 | plain | 40 | 1 |
| 4 | ZX300R | carbon | 1 | 300 | plain | 12 | 0 |
| 7 | PP120Q | carbon | 3 | 120 | twill | 28 | 1 |
First attempt (based on the explanation of MIN() given in MySQL documentation or, at least, on what I understood of it):
$sql = 'SELECT code, weight, weave, MIN(price)
FROM products
WHERE category="carbon" AND show="1"
GROUP BY code
ORDER BY weight ASC';
Second attempt (based on this answer here on SO):
$sql = 'SELECT a.code, a.weight, a.price, a.weave
FROM products a
INNER JOIN
(
SELECT code, weight, MIN(price) AS minprice, weave
FROM products
GROUP BY code
)
b ON a.code = b.code AND a.weave = b.weave AND a.price = b.minprice AND AND a.weight = b.weight
WHERE category="carbon" AND show="1"
ORDER BY a.weight ASC';
Third attempt (based on this other answer here on SO):
$sql = 'SELECT code, weight, weave, price
FROM products
INNER JOIN
(
SELECT MIN(price) price, code, weight, weave
FROM products
GROUP BY code
)
AS MIN ON MIN.code = products.code AND MIN.weight = products.weight AND MIN.weave = products.weave
WHERE category="carbon" AND show="1"
ORDER BY a.weight ASC';
It's probably useless say that none of these attempts produced the expected result; just the third method outputs something while the others two return 0 matches. I understood that in the 2nd and 3rd methods I'm nesting a query into a query but I can't figure out why they don't work.
You're close with your second attempt. But the only columns you should be joining on are code and price. weight and weave then come from the row that's selected by this join condition.
SELECT a.code, a.weight, a.price, a.weave
FROM products a
INNER JOIN
(
SELECT code, MIN(price) AS minprice
FROM products
GROUP BY code
)
b ON a.code = b.code AND a.price = b.minprice
WHERE category="carbon" AND show="1"
ORDER BY a.weight ASC
This is the same as the answers in the questions you linked to. None of them suggest adding other columns to the ON clause, so I'm not sure where that came from.

PHP MySQL Ranking will count order by number and sort by group

Let's say initially I has table like this without rank or already has rank if php code has running before
ID | STATUS | GRADE | RANK
1 | FAIL | 99 |
2 | FAIL | 95 |
3 | PASS | 40 |
4 | BAR | 99 |
5 | PASS | 70 |
6 | PASS | 85 |
7 | BAR | 80 |
8 | FAIL | 60 |
9 | BAR | 50 |
The ranking system should choose PASS > FAIL > BAR in order. But in that category, when start to enter new category the ranking system will count from previous.
Expected result:
ID | STATUS | GRADE | RANK
1 | FAIL | 99 | 4
2 | FAIL | 95 | 5
3 | PASS | 40 | 3
4 | BAR | 99 |
5 | PASS | 70 | 2
6 | PASS | 85 | 1
7 | BAR | 80 |
8 | FAIL | 60 | 6
9 | BAR | 50 |
Also if can show me some technique to edit the code so that in another day if i plan to upgrade the coding to
ID | STATUS | GRADE | RANK
1 | FAIL | 99 | 4
2 | FAIL | 95 | 5
3 | PASS | 40 | 3
4 | BAR | 99 | 7
5 | PASS | 70 | 2
6 | PASS | 85 | 1
7 | BAR | 80 | 8
8 | FAIL | 60 | 6
9 | BAR | 50 | 9
I have try edit and learning some codes that I found here but I not familiar with session variable. This code will use in cron job/day
You can use user variables to set a rank, and using a sub query joined against the table you want to update you can update the rank in the table.
Something like this:-
UPDATE sometable
INNER JOIN
(
SELECT id,
`status`,
grade,
#rank:=#rank + 1 AS rank
FROM
(
SELECT id,
`status`,
grade
FROM sometable
ORDER BY FIELD(`status`, 'PASS', 'FAIL', 'BAR'), Grade DESC
) sub0
CROSS JOIN (SELECT #rank:=0) sub1
) sub2
ON sometable.id = sub2.id
SET sometable.rank = sub2.rank
Note that I have used the FIELD function to order by the status. In this case it is not strictly necessary (as you could order by status DESC) but given the names of the status would not normally be expect to be in a meaningful alphabetic order FIELD allows you to order in a specified order.

Join is not working properly

I am new to SQL and trying to fetch data using join. Don't know what I am doing wrong. I have two tables.
Table record
recordID|activityName|userID
1 | sale | 5
2 | call | 5
3 | contact | 5
Table activity
activityID|activityData|userID
1 | 50 | 5
2 | 70 | 5
3 | xyz | 5
Result should be
recordID|activityName|activityData|userID
1 | sale | 50 | 5
2 | call | 70 | 5
3 | contact | xyz | 5
But it returns
recordID|activityName|activityData|userID
1 | sale | 50 | 5
2 | call | 70 | 5
3 | contact | xyz | 5
1 | sale | 50 | 5
2 | call | 70 | 5
3 | contact | xyz | 5
1 | sale | 50 | 5
2 | call | 70 | 5
3 | contact | xyz | 5
SELECT * FROM tblrecord tr, tblactivity ta WHERE tr.userID = ta.userID AND tr.userID = '5'
Why is it repeating the result.
PS. userID is the only common field, the activityID and recordID can be different.
First, follow a simple rule: Never use commas in the FROM clause. Always use explicit JOIN syntax.
Second, you seem to want a join on recordId and activityId:
SELECT *
FROM tblrecord tr JOIN
tblactivity ta
ON tr.userID = ta.userID AND
tr.recordId = ta.activityId
WHERE tr.userID = 5;
Also, don't use single quotes if the value is really a number.
Add
GROUP BY userID, activityID
to your query.

Filter fields from 1/n table using clause on multiple columns

ok, first of all sorry for the title, but I could not work out a better one :(
This is the problem:
I have two tables, properties and properties_rooms, linked each other by the propery ID.
properties table:
+---------------+------------+
| id_properties | pr_title |
+---------------+------------+
| 1 | test |
| 2 | dummy |
+---------------+------------+
properties_rooms table:
+---------------+-------------------+--------------+----------+
| id_prop_rooms | pro_id_properties | pro_id_rooms | pro_size |
+---------------+-------------------+--------------+----------+
| 1 | 1 | 4 | 5.00 |
| 2 | 1 | 18 | 17.00 |
| 3 | 2 | 6 | 12.00 |
| 4 | 2 | 24 | 11.00 |
| 5 | 1 | 4 | 10.00 |
| 6 | 1 | 6 | 10.00 |
| 7 | 1 | 6 | 12.00 |
+---------------+-------------------+--------------+----------+
I'm working on an advanced search, where users can search for a property that has more than a rooms of the same type (ie two bedrooms, 3 bathrooms and so on).
Sadly, I find myself stuck on this, since I can't "filter" the same dataset with multiple clause; if i have to filter only one there will be no problems, since I can use an HAVING clause.
I worked out this select:
SELECT id_properties, pro_id_rooms, COUNT(*) as total,
IF ((pro_id_rooms = 4 AND COUNT(*) >= 2) OR (pro_id_rooms = 6 AND COUNT(*) >= 2), 1, 0) as flag
FROM `properties`
INNER JOIN properties_rooms ON id_properties = pro_id_properties
WHERE id_properties IN (4,10)
GROUP BY id_properties, pro_id_rooms
ORDER BY id_properties
Inside the IN clause there are the properties that I know they have at least one of requested rooms. They came from a previous query since I have to work with GROUP BY and HAVING.
The IF part inside the select is built at run-time, since I get the information from the request.
This is the result:
+---------------+--------------+-------+------+
| id_properties | pro_id_rooms | total | flag |
+---------------+--------------+-------+------+
| 1 | 4 | 2 | 1 |
| 1 | 6 | 2 | 1 |
| 1 | 18 | 1 | 0 |
| 2 | 6 | 1 | 0 |
| 2 | 24 | 1 | 0 |
+---------------+--------------+-------+------+
I think it could work, I only need to add an HAVING flag > 0 and I'm done.
My question is, is there anything better?
Tables aren't very large: properties one could be something like 1k, rooms one about 10k.
I'm afraid that if the user puts too much rooms, the query would become an enormous IF statement...
SELECT id_properties, SUM(pro_id_rooms = 4) AS bedrooms, SUM(pro_id_rooms = 6) AS bathrooms
FROM `properties`
INNER JOIN properties_rooms ON id_properties = pro_id_properties
WHERE id_properties IN (4,10)
GROUP BY id_properties
HAVING bedrooms >= 3 AND bathrooms >= 2
Changes
SUM(pro_id_rooms = 4) AS bedrooms, SUM(pro_id_rooms = 6) AS bathrooms
For each checkbox the user has selected, you need a SUM(pro_id_rooms = x) AS nrofx in your WHERE.
HAVING bedrooms >= 3 AND bathrooms >= 2
This is where you check the number of a particular room.

Categories