SQL order by multiple condition - mysql

I have a table with 'name','status'-fail or success,'counts'- 1 to 100. I want to order it in such a way that names of only 'fail' should show on top together, then same name with fail and success together, then names with only success together.
Can we do it sql query language ?
Thank you.

Ok, this should work on most RDBMS:
SELECT A.*
FROM YourTable A
INNER JOIN (SELECT name,
COUNT(DISTINCT status) StatusCount,
MIN(status) MinStatus
FROM YourTable
GROUP BY name) B
ON A.name = B.name
ORDER BY CASE WHEN StatusCount = 1 AND MinStatus = 'fail' THEN 1
WHEN StatusCount = 2 THEN 2
ELSE 3 END, A.name, A.status

If it is MySQL
select *, 0 as o
from t
union all
select *, 1 as o
from t
order by
o = 1 and status != 'fail', o != 1, status = fail

Related

shows mysql records twice because of inner joining

In below query (Mentors) are 13 which shows me 26, while (SchoolSupervisor) are 5 which shows me 10 which is wrong. it is because of the Evidence which having 2 evidance, because of 2 evidence the Mentors & SchoolSupervisor values shows me double.
please help me out.
Query:
select t.c_id,t.province,t.district,t.cohort,t.duration,t.venue,t.v_date,t.review_level, t.activity,
SUM(CASE WHEN pr.p_association = "Mentor" THEN 1 ELSE 0 END) as Mentor,
SUM(CASE WHEN pr.p_association = "School Supervisor" THEN 1 ELSE 0 END) as SchoolSupervisor,
(CASE WHEN count(file_id) > 0 THEN "Yes" ELSE "No" END) as evidence
FROM review_m t , review_attndnce ra
LEFT JOIN participant_registration AS pr ON pr.p_id = ra.p_id
LEFT JOIN review_files AS rf ON rf.training_id = ra.c_id
WHERE 1=1 AND t.c_id = ra.c_id
group by t.c_id, ra.c_id order by t.c_id desc
enter image description here
You may perform the aggregations in a separate subquery, and then join to it:
SELECT
t.c_id,
t.province,
t.district,
t.cohort,
t.duration,
t.venue,
t.v_date,
t.review_level,
t.activity,
pr.Mentor,
pr.SchoolSupervisor,
rf.evidence
FROM review_m t
INNER JOIN review_attndnce ra
ON t.c_id = ra.c_id
LEFT JOIN
(
SELECT
p_id,
COUNT(CASE WHEN p_association = 'Mentor' THEN 1 END) AS Mentor,
COUNT(CASE WHEN p_association = 'School Supervisor' THEN 1 END) AS SchoolSupervisor,
FROM participant_registration
GROUP BY p_id
) pr
ON pr.p_id = ra.p_id
LEFT JOIN
(
SELECT
training_id,
CASE WHEN COUNT(file_id) > 0 THEN 'Yes' ELSE 'No' END AS evidence
FROM review_files
GROUP BY training_id
) rf
ON rf.training_id = ra.c_id
ORDER BY
t.c_id DESC;
Note that this also fixes another problem your query had, which was that you were selecting many columns which did not appear in the GROUP BY clause. Under this refactor, there is nothing wrong with your current select, because the aggregation take place in a separate subquery.
try adding this to the WHERE part of your query
AND pr.p_id IS NOT NULL AND rf.training_id IS NOT NULL
You can add a group by pr.p_id to remove the duplicate records there. Since, the group by on pr is not present as of now, there might be multiple records of same p_id for same ra
group by t.c_id, ra.c_id, pr.p_id order by t.c_id desc

How to combine two sql counts from same joined table

another annoying student here!
Today I spend hours trying to combine (select) 2 already joined SQL outputs + the ID of the original table in a single table output. which ultimately resulted in this query:
SELECT * FROM(
SELECT fd1.User_idUser,avg(fd1.caloryIntake)
AS 'workdays'
FROM fact_dailysnapshot fd1
INNER JOIN dim_day dd1 ON dd1.DATE_SK = fd1.DATE_SK
WHERE dd1.weekend_ind = 'N'
GROUP BY fd1.User_idUser
ORDER BY fd1.User_idUser) A,
(SELECT avg(fd1.caloryIntake) AS 'weekend'
FROM fact_dailysnapshot fd1
INNER
JOIN dim_day dd1 ON dd1.DATE_SK = fd1.DATE_SK
WHERE dd1.weekend_ind = 'Y'
GROUP BY fd1.User_idUser
ORDER BY fd1.User_idUser) B;
Which translates into…
Now this is a false result, the second column gives an almost constant value for all user entries. I think this must be solved with some kind of EXTRA join but I literally ran out of ideas. Thanks in advance..!
Your JOIN is missing an ON clause to relate dUser_idUser.
But, the simplest way to write the query uses conditional aggregation:
SELECT fd1.User_idUser,
avg(case when dd1.weekend_ind = 'N' then fd1.caloryIntake end) as weekday_avg,
avg(case when dd1.weekend_ind = 'Y' then fd1.caloryIntake end) as weekend_avg
FROM fact_dailysnapshot fd1 INNER JOIN
dim_day dd1
ON dd1.DATE_SK = fd1.DATE_SK
GROUP BY fd1.User_idUser
ORDER BY fd1.User_idUser;
This is one query instead of two.
If I understand correctly, this is what you are looking for:
SELECT A.User_idUser, A.workdays, B.weekend
FROM (
SELECT fd1.User_idUser, avg(fd1.caloryIntake) AS 'workdays'
FROM fact_dailysnapshot fd1
INNER JOIN dim_day dd1
ON dd1.DATE_SK = fd1.DATE_SK
WHERE dd1.weekend_ind = 'N'
GROUP BY fd1.User_idUser
ORDER BY fd1.User_idUser) A
JOIN
(SELECT fd1.User_idUser, avg(fd1.caloryIntake) AS 'weekend'
FROM fact_dailysnapshot fd1
INNER JOIN dim_day dd1
ON dd1.DATE_SK = fd1.DATE_SK
WHERE dd1.weekend_ind = 'Y'
GROUP BY fd1.User_idUser
ORDER BY fd1.User_idUser) B
ON A.User_idUser = B.User_idUser
Each query gives you all users by ID and their workdays or weekends. You need to JOIN the results of the two query on the user ID.

How to one column full result and max of that column value?

SELECT Max(c.vendor_id),c.vendors_id FROM (SELECT distinct a.vendor_id FROM service_master a,products b,vendors v,`vendor_addresses` ad WHERE a.cat_id= 242 AND a.service_id = b.s_sid AND a.is_active =1 AND b.isproductactive = 1 AND v.vendorid = a.vendor_id AND ad.vendorchild_id = a.vendor_id AND v.isvendoractive = 1 LIMIT 10) c ORDER BY c.vendor_id
Questions:
1)I want full result in vendor_id column
2)Max(vendor_id)result
How to get result in single query?
Not tested. But please try this.
select t1.id,t2.id
from detail t1
left join(
select max(id) as id
from detail
) t2 on 1 = 1
select id, ( select max(id) from detail internal_detail
where detail.id = internal_detail.id ) as max from detail

How to create multiple counts in a mysql statement

I have some trouble to count more than 2 counts in mysql statement.
My count(b.entry_id) as totalbooking wont work. What have i done wrong? Is the statement setup also correctly made​​?
This is how i tried:
"SELECT
t.restaurant_id as restaurant_id, ct.title as title,
count(DISTINCT t.cardid) as totalmembers,
count(t.restaurant_id) as totaltransactions,
count(b.entry_id) as totalbooking
from transactions as t
inner join exp_menucard_booking as b on (t.restaurant_id = b.entry_id)
inner join exp_channel_titles as ct on (t.restaurant_id = ct.entry_id)
inner JOIN exp_channel_data as cd on (ct.entry_id = cd.entry_id)
where t.cardid != 88888888 and ct.status = 'open'
group by t.restaurant_id
order by ct.title asc";
Use this pattern to count subsets of the total rowset:
sum( case when ColumnToBeTested = trueCondition then 1 else 0 end) as SubCount

Some sort of join statement?

How do I put these two queries into a single query?
select count(id) as cnt from {$site_id}.proofingv2_packages where active='1'
select count(id) as cnt from {$site_id}.proofingv2_package_options where active='1' and parent={$row["id"]} order by sort
$row['id'] is the id field from the first query. I am trying to determine if there are any valid packages. A valid package must be active and have at least 1 active option. Running 2 queries for this doesn't seem right.
Can anyone help?
select count(id) as cnt from
{$site_id}.proofingv2_packages pp
INNER JOIN
{$site_id}.proofingv2_package_options
pt ON pp.active = pt.Active AND
pp.Active = 1
if the id is the PK or FK on the same on both tables use this query
select count(id) as cnt from
{$site_id}.proofingv2_packages pp
INNER JOIN {$site_id}.proofingv2_package_options pt ON pp.id= pt.id
AND pp.Active = 1
SELECT IF(count(*) > 0, 1, 0) AS isValid
FROM {$site_id}.proofingv2_packages pp
INNER JOIN {$site_id}.proofingv2_package_options ppo ON ppo.parent = pp.id
WHERE pp.active = '1'
AND ppo.active = '1'
This should return 1 if there are valid packages or 0 if not