How to order table results by another rows value - mysql

I have created a query to select the record column in a table where other rows exist but i want to add an order by which orders by another rows value.
SELECT
record
FROM
record_attributes
GROUP BY
record
HAVING
sum(type = 'lead' AND option_name = 'pupil_cap' AND value > 0) > 0 AND
sum(type = 'lead' AND option_name = 'car_type' AND value = 'Manual') > 0 AND
sum(type = 'lead' AND option_name = 'instructor_areas_covered' AND value = '26') > 0 AND
sum(type = 'lead' AND option_name = 'diary_updates' AND value = '1') > 0
How can I order these results by another query in the same table with the following data:
ORDER BY record_attributes.value WHERE record_attributes.type = 'lead' AND record_attributes.option_name = 'instructor_rank'
And if the row doesn't exist, then use this:
ORDER BY record_attributes.value WHERE record_attributes.type = 'lead' AND record_attributes.option_name = 'instructor_start_date'

Not sure I understood correctly.
But something like this?
...
ORDER BY
MAX(CASE WHEN type = 'lead' AND option_name = 'instructor_rank' THEN value END),
MAX(CASE WHEN type = 'lead' AND option_name = 'instructor_start_date' THEN value END)
You can test it here on rextester.

Related

MySQL UPDATE -- ignore records not in CASE statement

How do you ignore records not inside the case statement when using CASE/WHEN/THEN?
For example, this statement will update three matching records as expected but will make all student records that do not match a WHEN/THEN clause to NULL
UPDATE table SET student = (CASE WHEN student = '10' THEN '100412'
WHEN student = '17' THEN '100295'
WHEN student = '26' THEN '100981'
END)
WHERE year = '2019';
How can you skip over records not inside the CASE statement and only change records that have a matching clause?
For skipping records not in case statement, you can use something like this
UPDATE table SET student = (CASE WHEN student = '10' THEN '100412'
WHEN student = '17' THEN '100295'
WHEN student = '26' THEN '100981'
END)
WHERE year = '2019' AND student IN ('10','17','26');
There a two solutions I think :
Add a where clause
UPDATE table SET student = (CASE WHEN student = '10' THEN '100412'
WHEN student = '17' THEN '100295'
WHEN student = '26' THEN '100981'
END)
WHERE year = '2019' AND student IN ('10','17','26');
Use else statement but that will scan the whole table for nothing :
UPDATE table SET student = (CASE WHEN student = '10' THEN '100412'
WHEN student = '17' THEN '100295'
WHEN student = '26' THEN '100981'
ELSE student
END)
WHERE year = '2019';
You could use a default case for that:
UPDATE table SET student = (CASE WHEN student = '10' THEN '100412'
WHEN student = '17' THEN '100295'
WHEN student = '26' THEN '100981'
ELSE student
END)
WHERE year = '2019';
Otherwise, if you want to minimize the load, just add all known student values to the WHERE clause. This triggers an update only on those rows that are really affected by a change
You can use in or = operator
WHERE year = '2019' AND (student = '10' or student = '17' or student ='26');

Group by a field that exist inside a nested query

i want to thank you for contributing to the answer here is an SQL fiddle
http://sqlfiddle.com/#!9/610e7/1
-- This query will return all the attributes of an issue
select * from dataissue where issue = '25998' .
What I want to do is :
sum(value) count(value)
where field = 'version(s)_corrigée(s)'
and value = 'Fermée'
and field = 'point_d_effort'
and value = 'récit'
and group it by value where field = 'version(s)_corrigée(s)'
for example this query return the group by but the sum explode because we use the field of the outer query :
sqlfiddle.com/#!9/610e7/4
I suspect that you want something like this:
select sum(case when field = 'point_d_effort' then value + 0 end), as v
sum(field = 'point_d_effort') as cnt
from dataissue
group by issue
having sum(field = 'version(s)_corrigée(s)' and value = 'Fermée') > 0 and
sum(field = 'Type de demande' and value = 'récit') > 0;
You have an entity-attribute-value (EAV) data structure. One method is to first aggregate by key. If you want the total across all issues, then you need another aggregation:
select sum(v), sum(cnt)
from (select sum(case when field = 'point_d_effort' then value + 0 end), as v
sum(field = 'point_d_effort') as cnt
from dataissue
group by issue
having sum(field = 'version(s)_corrigée(s)' and value = 'Fermée') > 0 and
sum(field = 'Type de demande' and value = 'récit') > 0
) t

MySQL sort by column and column value

I have a situation here, I am having a join of two tables to get records, where one table is storing key value pair in two different columns(wordpress user meta table).
So heres my query:
SELECT
um.user_id
FROM
sl_job_applications as ja,
sl_usermeta as um
WHERE
um.user_id = ja.user_id
AND ja.job_id = 3
AND ja.STAGE = 'Application'
AND ja.STATUS = 'In progress'
group by ja.user_id
order by case when (um.meta_key = 'CURRENT_TOTAL_EXPERIENCE') then -1 else 2 end,
um.meta_value asc
LIMIT 0 , 50;
The order by is not working here, my data is
user_id meta_key meta_value
3 CURRENT_TOTAL_EXPERIENCE 6
4 CURRENT_TOTAL_EXPERIENCE 2
5 CURRENT_TOTAL_EXPERIENCE 1
6
I hope you understand my table data,
My above query returns
6,4,5,3
But I am expecting this output:
6,5,4,3
Simply change the order by to have an aggregation function such as max() and the value:
order by min(case when (um.meta_key = 'CURRENT_TOTAL_EXPERIENCE') then -1 else 2 end),
min(case when (um.meta_key = 'CURRENT_TOTAL_EXPERIENCE') then um.meta_value end) asc
LIMIT 0 , 50;
The first checks that the meta_key with that value exists. The second extracts the value and does the sort.
Try this:
SELECT um.user_id
FROM sl_job_applications AS ja
INNER JOIN sl_usermeta AS um ON um.user_id = ja.user_id
WHERE ja.job_id = 3 AND ja.STAGE = 'Application' AND ja.STATUS = 'In progress'
GROUP BY ja.user_id
ORDER BY CASE WHEN (um.meta_key = 'CURRENT_TOTAL_EXPERIENCE') THEN -1 ELSE 2 END,
CAST(um.meta_value AS SIGNED) ASC
LIMIT 0, 50

Is it possible to change the order by "DESC/ASC" in a case statment - MySql

I have a select statement with a order by command. Now the order by command has a case statment based on the status of the record it sort by a different column. However, I need to also the order by DESC if the status = 1 else order by ASC.
How can I do this?
This is my current statement:
SELECT ph.phone_call_id AS id, ph.call_subject AS callSubject,
ph.trigger_on AS triggerOn,
ph.isAppointment,
IFNULL(ph.last_attempt_on, "") last_attempt_on,
ind.name AS industry,
ac.account_id,
ac.account_name AS accountName
FROM phone_calls AS ph
INNER JOIN accounts AS ac ON ph.account_id = ac.account_id
INNER JOIN industries AS ind ON ind.industry_id = ac.industry_id
INNER JOIN call_codes AS cc ON ph.call_code_id = cc.call_code_id
WHERE ac.status = 1
AND ph.status = '.$call_status.'
AND ph.owner_id = '. USER_ID .'
AND ac.do_not_call = 0
ORDER BY CASE WHEN ph.status = 1 THEN ph.trigger_on ELSE ph.last_attempt_on END
Is this what you want?
ORDER BY (CASE WHEN ph.status = 1 THEN ph.trigger_on end) DESC,
(case when ph.status <> 1 then ph.last_attempt_on END) ASC

SQL ORDER BY query

I want to have my table,rcarddet, ordered by "SDNO" (not primary key) in ascending order with the exception of "0". So it should turn out to be like:
1
1
2
.
.
10
0
0
My query now is:
SELECT *
FROM `rcarddet`
WHERE `RDATE` = '2011-05-25'
AND `RCNO` = '1'
AND `PLACE` = 'H'
AND `SDNO` != 0
ORDER BY `rcarddet`.`SDNO` ASC;
The easiest way
SELECT * FROM rcarddet
WHERE RDATE = '2011-05-25' and RCNO = '1'and PLACE = 'H'
ORDER BY CASE
WHEN rcarddet.SDNO = 0 THEN [max_number_for_the_type_of_SDNO]
ELSE rcarddet.SDNO
END ASC
SELECT *
FROM `rcarddet`
WHERE `RDATE` = '2011-05-25'
AND `RCNO` = '1'
AND `PLACE` = 'H'
ORDER BY
`SDNO` = 0,
`SDNO`;