How to combine multiple rows into one row - mysql

i want to combine multiple rows into one row.
the table type is dynamic
Table Room
room_id | room_name
-------------------
1 | room_A
2 | room_B
3 | room_C
Table Type
type_id | type_name
-------------------
1 | type_I
2 | type_II
3 | type_II
4 | type_IV
table Price
price_id | room_id | type_id | price
------------------------------------
1 | 1 | 1 | 100
2 | 1 | 2 | 150
3 | 1 | 3 | 200
4 | 1 | 4 | 250
5 | 2 | 1 | 100
6 | 2 | 2 | 200
7 | 2 | 3 | 300
8 | 2 | 4 | 400
9 | 3 | 1 | 150
10 | 3 | 2 | 250
11 | 3 | 3 | 350
12 | 3 | 4 | 450
what i want is something like this
| price
room |---------------------------------------
| type_I | type_II | type_III | type_IV
-----------------------------------------------
room_A | 100 | 150 | 200 | 250
room_B | 100 | 200 | 300 | 400
room_C | 150 | 250 | 350 | 450

Try this Query, Hope this helps you:
SELECT TR.Room_Name
,MAX(CASE WHEN P.Type_ID=1 THEN Price END)type_I
,MAX(CASE WHEN P.Type_ID=2 THEN Price END)type_II
,MAX(CASE WHEN P.Type_ID=3 THEN Price END)type_III
,MAX(CASE WHEN P.Type_ID=4 THEN Price END)type_IV
FROM TABLE_PRICE P
INNER JOIN TABLE_ROOM TR ON TR.Room_ID=P.Room_ID
INNER JOIN TABLE_TYPE TT ON TT.Type_ID=P.Type_ID
GROUP BY TR.Room_Name

Related

How to work out total distinct values minus grouped distinct values in MySQL

Given the sample table of:
+----+----------+---------+------+
| id | userName | storeId | cost |
+----+----------+---------+------+
| 1 | foo | 1 | 10 |
| 2 | bar | 1 | 10 |
| 3 | baz | 5 | 5 |
| 4 | baz | 3 | 20 |
| 5 | qux | 1 | 5 |
| 6 | qux | 4 | 20 |
| 7 | qux | 15 | 30 |
| 8 | qux | 17 | 40 |
| 9 | qux | 3 | 5 |
| 10 | quux | 6 | 20 |
+----+----------+---------+------+
I would like to work out how many people purchased at each store and how many did not. I want the report to display the results grouped by store.
I know the statement select storeId, count(distinct username) as total from purchases group by storeId provides me with how many people purchased in each store, but I want to subtract the result of the query select count(distinct userName) from purchases; in another column. I would expect the sample output to display as follows.
+---------+-----------+--------------+
| storeId | purchased | notPurchased |
+---------+-----------+--------------+
| 1 | 3 | 2 |
| 3 | 2 | 3 |
| 4 | 1 | 4 |
| 5 | 1 | 4 |
| 6 | 1 | 4 |
| 15 | 1 | 4 |
| 17 | 1 | 4 |
+---------+-----------+--------------+
You can use NOT condition with IN() function
As long a subse3lect gives back only only one,
you can use following
SELECT
storeId,
COUNT(DISTINCT username) AS total,
((SELECT
COUNT(DISTINCT userName)
FROM
purchases) - COUNT(DISTINCT username)) notPurchased
FROM
purchases
GROUP BY storeId
storeId | total | notPurchased
------: | ----: | -----------:
1 | 3 | 2
3 | 2 | 3
4 | 1 | 4
5 | 1 | 4
6 | 1 | 4
15 | 1 | 4
17 | 1 | 4
db<>fiddle here

how to show limited record if it the number of row reach value of specified fields

as a titled said, is it actually possible to do that ?,
so first i have
student
+------------+------- +---------+
| id_student | score_a|score_b |
+------------+--------+---------+
| 1 | 70 |80 |
+------------+--------+---------+
| 2 | 70 |90 |
+------------+--------+---------+
| 3 | 80 |70 |
+------------+--------+---------+
| 4 | 80 |70 |
+------------+--------+---------+
| 5 | 80 |90 |
+------------+--------+---------+
| 6 | 60 |70 |
+------------+--------+---------+
| 7 | 60 |80 |
+------------+--------+---------+
| 8 |40 |70 |
+------------+--------+---------+
then class
+----------+--------------+
| id_class | limit_people |
+----------+--------------+
| 1 | 1 |
+----------+--------------+
| 2 | 2 |
+----------+--------------+
| 3 | 2 |
+----------+--------------+
and register table
register
+-------------+-------------+----------+
| id_register | id_students | id_class |
+-------------+-------------+----------+
| 1 | 1 | 1 |
+-------------+-------------+----------+
| 2 | 1 | 2 |
+-------------+-------------+----------+
| 3 | 2 | 2 |
+-------------+-------------+----------+
| 4 | 2 | 3 |
+-------------+-------------+----------+
| 5 | 3 | 1 |
+-------------+-------------+----------+
| 6 | 3 | 3 |
+-------------+-------------+----------+
| 7 | 4 | 3 |
+-------------+-------------+----------+
| 8 | 4 | 2 |
+-------------+-------------+----------+
is there a way if let's say one of class reach the max limit based on class.limit_people field, can't be the records that contain those id_class will not be showed again instead they will be showed with other id_class that they had as well since 1 students can have 2 id_class?
for example : class.limit_people = 1 for id_class = 1 , and in the resulted table there's 2 records that using id_class=1 , can't it only be showed only once(the students that have the higher score on total?
current query :
SELECT
register.id_register,
register.id_students,
(student.score_a + student.score_b)*50/100 AS total,
register.id_class
FROM
`register`
LEFT JOIN
`student`
ON (register.id_students = student.id_student)
GROUP BY register.id_students
ORDER BY total DESC
by running on those query , resulted that i had
+-------------+-------------+-------+----------+
| id_register | id_students | total | id_class |
+-------------+-------------+-------+----------+
| 3 | 2 | 80 | 2 |
+-------------+-------------+-------+----------+
| 1 | 1 | 75 | 1 |
+-------------+-------------+-------+----------+
| 5 | 3 | 75 | 1 |
+-------------+-------------+-------+----------+
| 7 | 4 | 75 | 3 |
+-------------+-------------+-------+----------+
as you can see id_students = 3 with id_class=1 are showed on the table instead (max row =1 based on class.limit_people), result that i wanted is the one that showed id_class=3
+-------------+-------------+-------+----------+
| id_register | id_students | total | id_class |
+-------------+-------------+-------+----------+
| 3 | 2 | 80 | 2 |
+-------------+-------------+-------+----------+
| 1 | 1 | 75 | 1 |
+-------------+-------------+-------+----------+
| 6 | 3 | 75 | 3 | */ id_class = 3 instead of 1 since it's still not reach the max capacity
+-------------+-------------+-------+----------+
| 7 | 4 | 75 | 3 |
+-------------+-------------+-------+----------+
SELECT * FROM students WHERE score >=100 AND ROWNUM <= 3;
this is just to answer the question who got the highest score in just showing three rows.
0xb7BA52343f45927B9CEAeaaB16228CA6Eb9FE5a4

How to get right results from a query with user variable as a counter?

I have this table called results :
+----+--------+---------+-----------+
| id | result | user_id | odd_value |
+----+--------+---------+-----------+
| 1 | 1 | 100 | 2.5 |
| 2 | 1 | 100 | 2 |
| 3 | 1 | 100 | 1 |
| 4 | 1 | 100 | 3 |
| 5 | 1 | 100 | 1 |
| 6 | 1 | 100 | 2.1 |
| 7 | 1 | 100 | 3.5 |
| 8 | 1 | 100 | 1.8 |
| 9 | 1 | 100 | 1.6 |
| 10 | 1 | 100 | 2.5 |
| 11 | 1 | 100 | 1.8 |
| 12 | 1 | 100 | 1.2 |
| 13 | 1 | 100 | 2.2 |
| 14 | 1 | 200 | 3 |
| 15 | 1 | 200 | 4.1 |
| 16 | 1 | 200 | 2.5 |
| 17 | 1 | 200 | 1.5 |
| 18 | 1 | 200 | 1.2 |
| 19 | 1 | 200 | 6 |
| 20 | 1 | 200 | 3.1 |
| 21 | 1 | 200 | 2.9 |
| 22 | 1 | 300 | 2.2 |
| 23 | 1 | 300 | 2 |
| 24 | 1 | 300 | 3 |
| 25 | 1 | 300 | 2.1 |
| 26 | 1 | 300 | 2.7 |
| 27 | 1 | 300 | 2.3 |
| 28 | 1 | 300 | 2.1 |
| 29 | 1 | 300 | 3 |
| 30 | 1 | 300 | 3.4 |
| 31 | 1 | 300 | 2.1 |
| 32 | 1 | 300 | 1.7 |
| 33 | 1 | 300 | 3 |
| 34 | 1 | 300 | 4.2 |
| 35 | 1 | 300 | 2.2 |
+----+--------+---------+-----------+
I get some information from this table using this query :
SELECT
user_id,SUM(CASE WHEN F1=5 THEN 1 ELSE 0 END) AS bonus
FROM
(
SELECT
user_id,
CASE WHEN result=1 and #counter<5 THEN #counter:=#counter+1 WHEN result=1 and #counter=5 THEN #counter:=1 ELSE #counter:=0 END AS F1
FROM odds o
cross join (SELECT #counter:=0) AS t
) Temp
group by user_id
I use the previous query to add 1 to the bonus variable for each five continuous winnings (win means result=1).
so for each streak (1,1,1,1,1) i add one to the bonus variable and then I grouped them by user_id to get the bonus for each user.
I get this result of the query and the data above:
+---------+-------+
| user_id | bonus |
+---------+-------+
| 100 | 2 |
| 200 | 2 |
| 300 | 3 |
+---------+-------+
and those are wrong results for user_id=200 and user_id=300 because :
for user_id = 200 there are just 8 winnings so the bonus should be 1 (because it has just one streak).
for user_id = 300 there are just 14 winnings so the bonus should be 2 (because it has just tow streak).
I am not sure how your result related to matches table,
you can add back WHERE / INNER JOIN clause if you need.
Here is link to fiddle
And here is a query:
SET #user:=0;
select d.user_id,
sum(case when d.result = 1 then 1 else 0 end) as winnings,
sum(case when d.result = 2 then 1 else 0 end) as loses,
sum(case when d.result = 1 then d.odd_value else 0 end) as points,
f.bonus
FROM odds d
INNER JOIN
(
SELECT
user_id,SUM(bonus) AS bonus
FROM
(
SELECT
user_id,
CASE WHEN result=1 and #counter<5 AND #user=user_id THEN #counter:=#counter+1
WHEN result=1 and #counter=5 AND #user=user_id THEN #counter:=1
WHEN result=1 and #user<>user_id THEN #counter:=1
ELSE
#counter:=0
END AS F1,
#user:=user_id,
CASE WHEN #counter=5 THEN 1 ELSE 0 END AS bonus
FROM odds o
ORDER BY user_id
) Temp
group by user_id
)as f on f.user_id = d.user_id
group by d.user_id

select sum of product price for every 1 id productcategory

i want to find solution for my query problem. I need to find the SUM of all priceProduct*quantity and separated with each of productcategory. I have already made a query, but it takes longer time to executed it. this is my query,
SELECT
pb.ProductCategoryID,
pb.ProductCategoryDescription,
(SELECT
SUM((SELECT pd.HPP FROM `price details` pd WHERE pd.ProductID = pdt.ProductID ORDER BY pd.PriceDetailID DESC LIMIT 1)*
(SELECT StockProductBallance FROM `stock product` sp WHERE sp.ProductID = pdt.ProductID ORDER BY sp.StockProductID DESC LIMIT 1))
FROM product pdt
WHERE pdt.ProductCategoryID = pb.ProductCategoryID
) AS Total
FROM `product category` pb
GROUP BY pb.ProductCategoryID
this my example table
table product:
+------+-------+
| id_p | id_pc |
+------+-------+
| 1 | 3 |
| 2 | 4 |
| 3 | 3 |
| 4 | 4 |
+------+-------+
table productcategory:
+-------+---------+
| id_pc | pc_name |
+-------+---------+
| 3 | new_pc |
| 4 | old_pc |
+-------+---------+
table price details:
+---------------+------+-----+
| PriceDetailID | id_p | hpp |
+---------------+------+-----+
| 1 | 1 | 100 |
| 2 | 1 | 110 |
| 3 | 1 | 120 |
| 4 | 2 | 200 |
| 5 | 2 | 210 |
| 6 | 2 | 220 |
+---------------+------+-----+
table stockProduct:
+-----------------+------+---------------+
| id_stockProduct | id_p | stockballance |
+-----------------+------+---------------+
| 1 | 1 | 10 |
| 2 | 1 | 11 |
| 3 | 1 | 12 |
| 4 | 2 | 20 |
| 5 | 2 | 21 |
| 6 | 2 | 22 |
+-----------------+------+---------------+
Really need your help guys, for better query..

Calculate percentage for an area of study

I need help for generating a SQL for MySQL database.
I have two tables:
Students
student_Subjects
Students table:
+------------+---------+-----------------+
| id | name |area_of_study_id |
+------------+---------+-----------------+
| 1 | AAA | 1 |
| 2 | BBB | 2 |
| 3 | CCC | 1 |
| 4 | DDD | 3 |
| 5 | EEE | 4 |
| 6 | FFF | 1 |
| 7 | GGG | 2 |
| 8 | III | 1 |
+------------+---------+-----------------+
student_subjects table:
+------------+-------------------+------------------+
| id | student_id | subject_id |
| 1 | 1 | 1 |
| 2 | 2 | 1 |
| 3 | 1 | 3 |
| 4 | 1 | 2 |
| 5 | 3 | 1 |
| 6 | 6 | 1 |
| 7 | 7 | 3 |
| 8 | 4 | 6 |
+------------+-------------------+------------------+
I need to find out a subject's area of study based on students area of study. From above students table you can see that students have the freedom to choose the area of study. Sometimes, they can choose subjects which are not related to their area of study. So, in this case, we need to calculate area of study for a subject based on the student percentages who have taken the subjects.
Partial output:
+------------+-------------------+-----------------------------------+
|Total_students | subject_id |area_of_study_id | percentage |
+------------+-------------------+-----------------+-----------------+
| 3 | 1 | 1 | 75 |
| 1 | 1 | 2 | 25 |
| 1 | 3 | 1 | 50 |
| 1 | 3 | 2 | 50 |
| 1 | 2 | 1 | 100 |
| 1 | 6 | 3 | 100 |
+------------+-------------------+-----------------+-----------------+
From above partial output, we can see, 3 students choose a subject(i.e subject_id =1) have the area of study 1 and one student is from different area of study (i.e 2). So, we can say subject_id =1 is from area of study = 1.
if percentage 50% for a subject. we can choose any area of study between two, no matter which one.
Expected output:
+------------+-------------------+-----------------------------------+
|Total_students | subject_id |area_of_study_id | percentage |
+------------+-------------------+-----------------+-----------------+
| 3 | 1 | 1 | 75 |
| 1 | 3 | 1 | 50 |
| 1 | 2 | 1 | 100 |
| 1 | 6 | 3 | 100 |
+------------+-------------------+-----------------+-----------------+
Try it this way
SELECT subject_id, area_of_study_id, total_students, percentage
FROM
(
SELECT p.subject_id, p.area_of_study_id, p.total_students,
p.total_students / t.total_students * 100 percentage
FROM
(
SELECT COUNT(*) total_students, ss.subject_id, s.area_of_study_id
FROM students s JOIN student_subjects ss
ON s.id = ss.student_id
GROUP BY ss.subject_id, s.area_of_study_id
) p JOIN
(
SELECT ss.subject_id, COUNT(*) total_students
FROM students s JOIN student_subjects ss
ON s.id = ss.student_id
GROUP BY ss.subject_id
) t ON p.subject_id = t.subject_id
ORDER BY percentage DESC
) q
GROUP BY subject_id;
Output:
| SUBJECT_ID | AREA_OF_STUDY_ID | TOTAL_STUDENTS | PERCENTAGE |
|------------|------------------|----------------|------------|
| 1 | 1 | 3 | 75 |
| 2 | 1 | 1 | 100 |
| 3 | 1 | 1 | 50 |
| 6 | 3 | 1 | 100 |
Here is SQLFiddle demo