group_concat and group by are NOT working together - mysql

I have looked for the answer, but I couldn't find, so hopefully you can help me.
I'm trying to get a list of jobs grouped by 'vacatureID' and 'organisatieID'.
But I can only get one of them to work.
Could someone please advise?
Thanks.
SELECT
tblVacature.vacatureNaam,
tblVacature.vacatureCode,
DATE_FORMAT(tblVacature.vacatureDatumToegevoegd,'%d-%m'),
MAX(tblVacature.vacatureSuper),
tblOrganisatie.organisatieID,
tblOrganisatie.organisatieNaam,
tblOrganisatie.organisatieNaamConvert,
GROUP_CONCAT(tblSpecialisme.specialismeNaam
ORDER BY CASE
WHEN specialismeNaam = 'BLABLA'
THEN 1 WHEN specialismeNaam = 'BLABLA 2'
THEN 2 WHEN specialismeID = '0'
THEN 4 ELSE 3 END, specialismeNaam ASC) AS specialismeNamen,
GROUP_CONCAT(tblSpecialisme.specialismeNaamConvert
ORDER BY CASE
WHEN specialismeNaam = 'BLABLA'
THEN 1 WHEN specialismeNaam = 'BLABLA 2'
THEN 2 WHEN specialismeID = '0'
THEN 4 ELSE 3 END, specialismeNaam ASC) AS specialismeNamenConvert
FROM tblVacature
LEFT JOIN tblOrganisatie ON (tblVacature.vacatureOrganisatie = tblOrganisatie.organisatieID)
LEFT JOIN tblSpecialisme ON FIND_IN_SET(tblSpecialisme.specialismeID, REPLACE(tblVacature.vacatureSpecialisme, ' ', ','))
WHERE
vacatureActive = '1'
AND vacatureDatumToegevoegd <= ?
GROUP BY vacatureID, organisatieID
ORDER BY MAX(vacatureSuper) DESC, tblVacature.vacatureDatumToegevoegd DESC

Related

Doctrine 2 DQL CASE WHEN in Count

I have this Query in native MySQL Code
SELECT *
FROM `turn`
LEFT JOIN (
poi
) ON ( turn.id = poi.turn_id )
GROUP BY turn.id
ORDER BY count( case when poi.image = 1 then 1 else null end) DESC;
I need to rebuild this in Doctrine 2 DQL
My attempt so far is this:
SELECT t, COUNT((CASE WHEN Bundle\Entity\Poi p.image = 1 then 1 ELSE NULL END)) AS num
FROM Bundle\Entity\Turn t
JOIN t.pois p
GROUP BY t.id
ORDER BY num DESC
And im getting this error:
An exception has been thrown during the rendering of a template ("[Syntax Error] line 0, col 99: Error: Expected end of string, got '.'") in Bundle:Admin:showTurnsFiltered.html.twig at line 75.
What am i doing wrong?
I found it by myself after hours of trying and searching, it's working with this DQL:
$dql = 'SELECT t,
SUM(CASE WHEN p.image = 1 THEN 1 ELSE 0 END) AS numImage
FROM Bundle\Entity\Turn t
JOIN t.pois p
GROUP BY t.id
ORDER BY numImage DESC';
Important that you need to use SUM instead of COUNT
You need to use ResultSetMappingBuilder. It would look something like :
public function getTurn()
{
$rsm = new ResultSetMappingBuilder($this->_em);
$rsm->addRootEntityFromClassMetadata('Foo\BarBundle\Entity\Turn', 't');
$rsm->addJoinedEntityFromClassMetadata('Foo\BarBundle\Entity\Poi', 'p', 't', 'poi', array('id' => 'poi_id'));
$rsm->addScalarResult('ImageCount', 'ImageCount');
$sql = 'SELECT t.id, t.foo, t.bar,
SUM(CASE WHEN p.image = 1 then 1 else null end) ImageCount,
FROM Turn t
INNER JOIN poi p ON t.id = p.turn_id
ORDER BY ImageCount DESC';
$query = $this->_em->createNativeQuery($sql, $rsm);
return $query->getScalarResult();
}
note: you might need to change $query->getScalarResult()to $query->getResult().

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

How can I select the rest of the row with DISTINCT?

I have a table where I keep messages and one where I keep users.
I want to get all the users that interactioned (send or received a message) with user_id 1.
This query works:
http://sqlfiddle.com/#!2/6a2f3/1
EDIT:
SELECT DISTINCT
(CASE WHEN `user_to_id` = 1 THEN `user_from_id` ELSE `user_to_id` END) `user_id`,
users.*
FROM `messages`
INNER JOIN users
ON (CASE WHEN `user_to_id` = 1 THEN `user_from_id` ELSE `user_to_id` END) = users.user_id
WHERE `user_to_id` = 1 OR `user_from_id` = 1
ORDER BY `time` DESC
But if I add to SELECT the message column, it returns duplicate records:
http://sqlfiddle.com/#!2/6a2f3/2
EDIT:
SELECT DISTINCT
(CASE WHEN `user_to_id` = 1 THEN `user_from_id` ELSE `user_to_id` END) `user_id`,
`messages`.`message`,
users.*
FROM `messages`
INNER JOIN users
ON (CASE WHEN `user_to_id` = 1 THEN `user_from_id` ELSE `user_to_id` END) = users.user_id
WHERE `user_to_id` = 1 OR `user_from_id` = 1
ORDER BY `time` DESC
How can I fix that?
And also, I see that it orders the results after the "DISTINCT" selection was made. The first query should return the results inverted because the row with message_id 2 has time 3.
Is there a way I can order them before the "DISTINCT"?
EDIT 2: I wasn't clear about the question. I want to select only the last message for a matched user_id.
Do you want something like this?
SELECT *
FROM (
SELECT
users.*,
(SELECT `message` from messages
WHERE
(CASE WHEN `user_to_id` = 1 THEN `user_from_id` ELSE `user_to_id` END) = users.user_id
AND (`user_to_id` = 1 OR `user_from_id` = 1)
ORDER BY `time` DESC limit 1
) AS message
FROM users
) a
WHERE message IS NOT NULL
SQL Fiddle
It's not returning duplicate records, you have two records with User_ID = 2.
I'm confused by what you want them to be ordered by. If you want to order them in the inverted order, just remove 'DESC'

SQL statement for GROUP BY

I am really stucked with one sql select statement.
This is output/result which I get from sql statement below:
WHAT I need: I need to have columns assignedVouchersNumber and usedVouchersNumber together in one row by msisdn. So for example if you can see "msisdn" 723709656 there are two rows now.. one with assignedVouchersNumber = 1 and second with assignedVouchersNumber = 1 too.
But I need to have it in one row with assignedVouchersNumber = 2. Do you now where is the problem?
SELECT eu.msisdn,
eu.id as userId,
sum(case ev.voucherstate when '1' then 1 else 0 end) as assignedVouchersNumber,
sum(case ev.voucherstate when '2' then 1 else 0 end) as usedVouchersNumber,
ev.extra_offer_id,
ev.create_time,
ev.use_time,
ev.id as voucherId,
ev.voucherstate
FROM extra_users eu
JOIN (SELECT sn.msisdn AS telcislo,
stn.numberid
FROM stats_number sn
JOIN stats_target_number AS stn
ON ( sn.numberid = stn.numberid )
WHERE stn.targetid = 1) xy
ON eu.msisdn = xy.telcislo
JOIN extra_vouchers AS ev
ON ( eu.id = ev.extra_user_id )
WHERE ev.create_time BETWEEN '2012-07-23 00:00:00' AND '2013-08-23 23:59:59'
AND ev.use_time <= '2013-08-23 23:59:59'
AND ev.use_time >= '2012-07-23 00:00:00'
AND ev.voucherstate IN ( 1, 2 )
AND Ifnull(ev.extra_offer_id IN( 2335, 3195, 30538 ), 1)
GROUP BY eu.msisdn, ev.extra_offer_id, ev.voucherState
ORDER BY eu.msisdn ASC
You have two different extra_offer_id for same msisdn and VouchersNumber. Thats why you get two rows.
I got it... there should not be groupping by ev.voucherState in
GROUP BY eu.msisdn, ev.extra_offer_id, ev.voucherState
After then I have removed ev.voucherState it is working now.

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