php mysql select lowest value from multiple coloumn - php

i have database with this condition :
table hotel -----> table hotel price
table hotel :
hotel_id | hotel_name |
1 hotel1
2 hotel2
table hotel price
price_id | hotel_id | room_type | single | Double | extra |
1 1 superior 5 10 20
2 1 deluxe 3 5 10
and i would show start smallest price from hotel1
hotel1 star from "smallest value"
i tried with this but not work
$query = ("SELECT LEAST(COL1,COL2,COL3) FROM rug WHERE COL1 != '' AND COL2!= '' AND COL3 != ''");
$result=mysql_query($query);
if (!$result) {
die('Invalid query: ' . mysql_error());}
$num=mysql_numrows($result);
$i=0;
while ($i < $num)
{
$pricing[$i]=mysql_result($result, $i);
$i++;
}
sort($pricing);
$lowest_price = $pricing[0]; //lowest price
thank raymond for the answer this is almost correct
select
*
, least(single, `double`, extra) as lowest_price
from hotel_price
where
hotel_id = 1
order by
lowest_price
;
with this will show lowest_price column at hotel price table
PRICE_ID HOTEL_ID ROOM_TYPE SINGLE DOUBLE EXTRA HOTEL_NAME LOWEST_PRICE
2 1 deluxe 3 5 10 hotel1 3
1 1 superior 5 10 20 hotel1 5
but i want just show one lowest price from lowest_price column
the smallest is 3
Any thoughts? Thanks!

Not completely sure if you need this..
if you know the id of hotel with name "hotel1" already
select
*
, least(single, `double`, extra) as lowest_price
from hotel_price
where
hotel_id = 1
order by
lowest_price
;
If you don't know the id of the hotel you need to join
select
*
, least(single, `double`, extra) as lowest_price
from
hotel_price
inner join
hotel
on
hotel_price.hotel_id = hotel.hotel_id
where
hotel.hotel_name = 'hotel1'
order by
lowest_price
;
see http://sqlfiddle.com/#!2/f947b/3 for demo note the demo has more queries what should give you the same results

By your SQL syntax I presume you are using MySQL. Than you can solve this by this approach:
SELECT
(SELECT COL1 from rug) as myField
UNION
(SELECT COL2 from rug)
UNION
(SELECT COL3 from rug)
order by myField ASC LIMIT 1

Related

I need help writing a sql query to concat multiple fields

I have table with following information
id | order_id | batch_id | bucket_id | menu_id | product_id | type_id | size
1 | 1 | 1 | 1 | 1 | 1 | 1 | small
2 | 1 | 1 | 1 | 1 | 5 | 1 | small
3 | 1 | 1 | 1 | 1 | 5 | 1 | medium
I want to achieve following
order_id | batch_id | product1 | product5
1 | 1 | 1 x small| 1 x small, 1 medium
Is this possible to write a query to achieve this?
It's possible in MySQL using this kind of query:
SELECT order_id, batch_id,
GROUP_CONCAT(CASE WHEN product_id=1 THEN CONCAT(type_id,' x ', size) END) AS product1,
GROUP_CONCAT(CASE WHEN product_id=5 THEN CONCAT(type_id,' x ', size) END) AS product5
FROM table1
GROUP BY order_id, batch_id
The problem with this is that it's not dynamic so if you have hundreds, thousands of products, the query will be very hard to maintain. One possible solution in MySQL is using prepared statement. Here is an updated example after #ggordon spotted that my previous attempt show duplicates:
SET #columns := (SELECT GROUP_CONCAT(CONCAT("GROUP_CONCAT(CASE WHEN product_id=",product_id,"
THEN CONCAT(cnt,' x ', size) END)
AS product",product_id,"
"))
FROM (SELECT DISTINCT product_id FROM table1) t1);
SET #query := CONCAT('SELECT order_id, batch_id, ',#columns,'
FROM (SELECT product_id, order_id, batch_id, size, COUNT(*) cnt
FROM table1 GROUP BY product_id, order_id, batch_id, size) t1
GROUP BY order_id, batch_id');
PREPARE stmt FROM #query ;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
There are 2 variables being used in there and I named each variable to represent what is it (hopefully).
Demo fiddle
The following query would return the desired data you would need
SELECT
order_id,
batch_id,
product_id,
concat(
count(product_id),
' x ',
size
) as size_cnt
FROM
t1
GROUP BY
order_id,
batch_id,
product_id,
size;
order_id
batch_id
product_id
size_cnt
1
1
1
1 x small
1
1
5
1 x small
1
1
5
1 x medium
View working demo on DB Fiddle
However, in order to get it in the desired format, you would need to pivot the data. You could achieve this with the assistance of group_concat as shown in the sql example below:
SELECT
order_id,
batch_id,
-- we can generate from here
REPLACE(
GROUP_CONCAT(
',',
CASE
WHEN product_id=1 THEN size_cnt
END
),
',,',
','
) as product1,
REPLACE(
GROUP_CONCAT(
',',
CASE
WHEN product_id=5 THEN size_cnt
END
),
',,',
','
) as product5
-- to here. See explanation below
FROM (
SELECT
order_id,
batch_id,
product_id,
concat(
count(product_id),
' x ',
size
) as size_cnt
FROM
t1
GROUP BY
order_id,
batch_id,
product_id,
size
) t2
GROUP BY
order_id,
batch_id
order_id
batch_id
product1
product5
1
1
,1 x small
,1 x small,1 x medium
View working demo on DB Fiddle
However, as you can see, you would have to know the product_ids before hand for the desired columns.
If you are uncertain about the product ids that you will have, writing a dynamic query would be helpful here. You could start by getting all the product_ids.
I'm using the DB facade from Laravel here, however, you may use the Eloquent ORM or other methods to achieve the following:
//I have a collection of product ids i.e. `collect([1,5])` based on your example
$productIds = DB::select("select distinct product_id from t1")
->pluck('product_id');
Then generating a dynamic sql query to run on your table
$productExpression = DB::select("select distinct product_id from t1")
->pluck('product_id')
//for each product id let us return an sql expression
->map(function($productId){
return "
REPLACE(
GROUP_CONCAT(
',',
CASE
WHEN product_id=$productId THEN size_cnt
END
),
',,',
','
) as product$productId
";
})
//combine the expressions into one string
->join(",");
We can now create a combined query as
$combinedQuery="
SELECT
order_id,
batch_id,
$productExpression
FROM (
SELECT
order_id,
batch_id,
product_id,
concat(
count(product_id),
' x ',
size
) as size_cnt
FROM
t1
GROUP BY
order_id,
batch_id,
product_id,
size
) t2
GROUP BY
order_id,
batch_id;
";
//running the query to retrieve the results
$results = DB::select($combinedQuery);
Let me know if this works for you.
If you are using php with either PDO or mysqli you can get PHP to concat the fields.
$result = $db->query("SELECT * FROM TABLE");
while($row = $result->fetch_assoc()) {
//do stuff with data
$product .= $row["product_id"] . " x " . $row["size"].", ";
}

how to retrieve the type of value which is there more number of times in a column in a table and count of it?

s.no Name type of vehicle allotted
1 ram bus
2 krish car
3 raj bus
4 albert car
5 johnson bike
6 raghu car
consider this is a table now i want to retrieve the type of vehicle which is there more number of times in the table and count of it. is there any particular method(query).
You have to use COUNT and GROUP BY.
Count will give you the number of rows grouped by type field.
SELECT COUNT(id) as count, type FROM table_name GROUP BY type
The output should be like this:
count | type
2 | bus
3 | car
1 | Bike
If you need just the highest one, append to the query:
ORDER BY count DESC LIMIT 1
I think you have to count and select the top 1 row.
Query
SELECT t.* FROM(
SELECT `type`, COUNT(`type`) `count`
FROM `your_table_name`
GROUP BY `type`
)t
ORDER BY `count` DESC LIMIT 1;

Get next and previous records within the same query

I'm having this PDO query to call data from a MySQL.
$sql = "SELECT itemName FROM furniture WHERE itemID = :item";
While calling for this particular itemName, is it possible to get the next and previous itemNames by using its itemID within this same query itself without having to write a new query to get the next and previous itemNames?
e.g.
if
itemID | itemName
___________________________
553 | Mahogani Black Chair
554 | Teak Round Table
555 | Thulang Relaxing Chair
556 | Teak Relaxing Chair
$sql = "SELECT itemName FROM furniture WHERE itemID = :item";
$stmt = $connect->prepare($sql);
$stmt->execute(array(':item'=>"554"));
$rslt = $stmt->fetchAll(PDO::FETCH_ASSOC);
I'm looking away of getting Teak Round Table and Mahogani Black Chair and Thulang Relaxing Chair
Please use this code:
(SELECT itemName FROM furniture WHERE itemID < 554 order by itemID desc limit 1)
UNION
(SELECT itemName FROM furniture WHERE itemID >= 554 order by itemID asc limit 2)
For Example code :
MyTable:
================
id Store_name
================
1 English
2 French
3 Tamil
4 Uk
5 US
<?php
$con = mysqli_connect("localhost","root","ramki","ramki");
$sql = "(SELECT store_name FROM store WHERE id < 2 order by id desc limit 1)
UNION
(SELECT store_name FROM store WHERE id >= 2 order by id asc limit 2)";
$query = mysqli_query($con,$sql);
while ($row = mysqli_fetch_assoc($query)) {
echo $row['store_name'];
echo "<br>";
}
?>
$sql = "SELECT itemName FROM furniture WHERE itemID IN (:item-1, :item, :item+1) ORDER BY itemID";
For iterating the results, you can also use PDO fetch() function to get each row.

Find Students who have registered in selected subject by Dropdown in php

StudentID | SubCode | SubName
-------------------------------
1 1 Math
1 2 Science
1 3 English
2 1 Math
2 2 Science
3 2 Science
4 1 Math
4 3 English
This is my subject table.
How can I find students who have registered as following
Students who have registered in only Maths NOT in English and Science
Students who have registered In Maths And English NOT Science
Students who have registered In Science And Maths And English
in a single SQL query.
I tried as this way
SELECT DISTINCT
`stud_id` FROM `subj_assign`
WHERE
`subj_id` = '1,2'
AND STATUS = '1'
ORDER BY
`subj_assign`.`stud_id` ASC
AND Also This way tried but Not Working
SELECT stud_id FROM subj_assign GROUP BY stud_id
HAVING Count(CASE WHEN subj_id = '1' AND
status='1' THEN 1 END) = 1 AND
Count(CASE WHEN `subj_id` = '2' AND
status='1' THEN 1 END) = 1
its rum for me. may be its help for you also.
SELECT stud_id FROM subj_assign GROUP BY stud_id
HAVING Count(CASE WHEN subj_id = '1' AND
status='1' THEN 1 END) = 1 AND
Count(CASE WHEN `subj_id` = '2' AND
status='1' THEN 1 END) = 1
then compare with total subject of student and filtered subjects with condition
Try this:-
SELECT
(SELECT DISTINCT StudentID FROM subject WHERE SubName = 'Math' AND StudentID NOT IN ( SELECT DISTINCT StudentID FROM subject WHERE SubName IN ('English', 'Science')) AS STUD_ONLY_IN_MATHS,
(SELECT DISTINCT StudentID FROM subject WHERE SubName in ('Math', 'English') AND StudentID NOT IN ( SELECT DISTINCT StudentID FROM subject WHERE SubName IN ('Science')) AS STUD_IN_MATHS_AND_ENGLISH,
(SELECT DISTINCT StudentID FROM subject WHERE SubName in ('Math', 'English', 'Science') AS STUD_IN_MATHS_ENGLISH_SCIENCE);
You can join the table with the table itself grouped by StudentID. That way you'll be able to test the number of rows and the SubCode at the same time.
SELECT DISTINCT tmp.StudentID
FROM subj_assign tmp JOIN (SELECT StudentID, COUNT(*) as total
FROM subj_assign
GROUP BY StudentID) tmpG on tmp.StudentID = tmpG.StudentID
WHERE (tmp.SubCode = 1 and total = 1) --Only Math
OR (total = 2 and SubCode != 2) --No Science
OR total = 3 --Math, English, Science

MySql Tally system with php

I'm trying to condense data that I have in my database into rows with their points tallied to see the most popular.
If I had a data table like:
`data`
item1 item2
1
1 2
1 3
1 3
2 3
And wanted the condensed version to be:
`data_sum`
item1 item2 Tally
1 2 2
1 3 3
2 3 1
How would I achieve this? I have somewhat of an idea here:
$popdata = mysql_query("SELECT * FROM data");
while($add = #mysql_fetch_array($popdata)){
$qitem1 = "SELECT * FROM data_sum WHERE item1='".$add['item1']."'";
$ritem1 = mysql_query($qitem1);
if(mysql_num_rows($ritem1) > 0){
$qitem2 = "SELECT * FROM data_sum WHERE item2='".$add['item2']."'";
$ritem2 = mysql_query($qitem2);
if (mysql_num_rows($ritem2) > 0){
$sql = "UPDATE Tally=Tally + 1 WHERE item1='".$add['item1']."' AND item2='".$add['item2']."'";
$update = mysql_query($sql);
}
else{
$sql = "INSERT INTO data_sum (item1, item2) VALUES('$item1', '$item2')";
$insert = mysql_query($sql);
}
else{
$sql = "INSERT INTO data_sum (item1, item2) VALUES('$item1', '$item2')";
$insert = mysql_query($sql);
}
Yes, I know the total tallies are one more than the rows in the first table. I want the rows with a null column to count towards both tallies with a common factor. This file is going to go through thousands of rows so I want utmost efficiency! Thanks!
All you would need to do is create a new table and then combine an INSERT statement with a GROUP BY'd SELECT statement. This would COUNT() the number of times item1 and item2 were the same and store them in the new tally'd table.
Something along the lines of:
INSERT INTO new_tally_table (item1, item2, Tally)
SELECT item1, item2, COUNT(*)
FROM table
GROUP BY item1, item2
Edit:
Actually re-read the last bit of your question. Think what you want is something like this:
SELECT item1, item2, COUNT(*)
FROM (
SELECT i1.item1, i2.item2
FROM table1 as i1
INNER JOIN (
SELECT DISTINCT item1, item2
FROM table1 WHERE item2 IS NOT NULL
) as i2 ON (i1.item1 = i2.item1)
WHERE i1.item2 IS NULL
UNION ALL
SELECT item1, item2
FROM table1
WHERE item2 IS NOT NULL
) as t
GROUP BY item1, item2
There's probably a better way of writing that though.
There may be a simpler solution, but I can't think of it...
DROP TABLE IF EXISTS my_table;
CREATE TABLE my_table
(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
,item1 INT NULL
,item2 INT NULL
);
INSERT INTO my_table (item1,item2) VALUES
(1 ,NULL),
(1 ,2),
(1 ,3),
(1 ,3),
(2 ,3);
SELECT x.item1
, x.item2
, COUNT(DISTINCT y.id)
FROM my_table x
JOIN my_table y
ON y.item1 = x.item1
AND (y.item2 = x.item2 OR y.item2 IS NULL)
AND y.id <= x.id
JOIN
( SELECT item1
, item2
, MAX(id) max_id
FROM my_table
GROUP
BY item1
, item2
) z
ON z.item1 = x.item1
AND z.item2 = x.item2
AND z.max_id = x.id
WHERE x.item2 <> 0
GROUP
BY x.id;
+-------+-------+----------------------+
| item1 | item2 | COUNT(DISTINCT y.id) |
+-------+-------+----------------------+
| 1 | 2 | 2 |
| 1 | 3 | 3 |
| 2 | 3 | 1 |
+-------+-------+----------------------+

Categories