SQL ORDER BY query - mysql

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`;

Related

Output of 3 queries

Got this 3 in 1 query:
SELECT * FROM
(
SELECT mesures.date j, AVG(mesures.valeur) maxi
FROM mesures
JOIN plages_horaire ON mesures.id_plage = plages_horaire.id_plage
WHERE MONTH(mesures.date) = '9' AND YEAR(mesures.date) = '2016' AND mesures.code_station = 'P02SE' AND mesures.id_crit = '1' AND mesures.id_type = '1'
GROUP BY mesures.date
) maxi
,
(
SELECT AVG(mesures.valeur) mini
FROM mesures
JOIN plages_horaire ON mesures.id_plage = plages_horaire.id_plage
WHERE MONTH(mesures.date) = '9' AND YEAR(mesures.date) = '2016' AND mesures.code_station = 'P02SE' AND mesures.id_crit = '1' AND mesures.id_type = '2'
GROUP BY mesures.date
) mini
,
(
SELECT AVG(mesures.valeur) moy
FROM mesures
JOIN plages_horaire ON mesures.id_plage = plages_horaire.id_plage
WHERE MONTH(mesures.date) = '9' AND YEAR(mesures.date) = '2016' AND mesures.code_station = 'P02SE' AND mesures.id_crit = '1' AND mesures.id_type = '3'
GROUP BY mesures.date
) moy
GROUP BY j
Problem is that I get what I want excepting values of the 2 last columns are the same at every rows:
query output
I believe it's because of the GROUP BY.
From what I can see from your query, you don't need the plage_horaire table. You can also simplify the logic greatly by using conditional aggregation:
SELECT m.date,
AVG(CASE WHEN m.id_type = 1 THEN m.valeur END) maxi,
AVG(CASE WHEN m.id_type = 2 THEN m.valeur END) mini,
AVG(CASE WHEN m.id_type = 3 THEN m.valeur END) maxmoy,
FROM mesures m
WHERE MONTH(m.date) = 9 AND YEAR(m.date) = 2016 AND
m.code_station = 'P02SE' AND m.id_crit = 1 AND m.id_type IN (1, 2, 3)
GROUP BY m.date ;
Notice that I also removed the quotes from the numeric constants. MONTH() and YEAR() return numbers, so quotes are not appropriate. I am guessing that the ids are numeric as well.

Mysql Query for converting currency and sorting by maxprice

I have and SQL query which sorts the properties based on price but when, I add and IF clause with Having it throws an error. Here is my Query
SELECT pp_propertylisting.id AS pid,
pp_propertylisting.title,
pp_propertylisting.city,
pp_propertylisting.street,
pp_propertylisting.country,
pp_propertylisting.bedrooms,
pp_propertylisting.bathrooms,
pp_propertylisting.termsconditions,
pp_propertyprice.currency,
pp_propertyimage.imageurl,
IF(pp_propertyprice.currency='dollar',Max(pp_propertyprice.pricepernight)*0.5,Max(pp_propertyprice.pricepernight)) AS maxiprice,
pp_propertyimage.title AS imgtitle,
pp_propertyprice.begindate,
(SELECT max(pp_propertyprice.pricepernight)
FROM pp_propertyprice
WHERE pp_propertyprice.propertyid = pp_propertylisting.id) AS maxprice,
pp_propertyprice.enddate,
pp_propertylisting.latitude,
pp_propertylisting.longitude,
pp_propertylisting.property_maxpeople,
pp_propertylisting.size,
pp_propertylisting.buildingsize,
pp_propertylisting.slug,
pp_propertylisting.cityslug,
pp_propertylisting.countryslug,
pp_propertylisting.continentslug,
pp_propertylisting.regionslug
FROM pp_propertyimage,
pp_propertylisting,
pp_propertyuntidetails1,
pp_propertyprice
WHERE pp_propertyuntidetails1.propertyid = pp_propertylisting.id
AND pp_propertylisting.id = pp_propertyimage.propertyid
AND pp_propertyimage.recordlistingid = 1
AND pp_propertylisting.archivestatus = 0
AND pp_propertyimage.delstatus = 0
AND pp_propertyprice.propertyid = pp_propertylisting.id
AND pp_propertylisting.delstatus=0
AND pp_propertylisting.approvestatus = 1
GROUP BY pp_propertylisting.id
ORDER BY maxprice DESC,
pp_propertylisting.title DESC HAVING maxiprice > 0
AND maxiprice < 5000
Can you tell me why there is an syntax error.
The having clause goes after group by and before order by:
SELECT . . .
GROUP BY pp_propertylisting.id
HAVING maxiprice > 0 AND maxiprice < 5000
ORDER BY maxprice DESC, pp_propertylisting.title DESC

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().

How to select an "AS field" in MySql?

I have a Query which is separated in different parts. (distance, score and rank)
SELECT Entry.*, Address.*,
(6367.41 * SQRT(2 * (1-cos(RADIANS(Entry.latitude)) * cos(0.92640848333131) * (sin(RADIANS(Entry.longitude)) * sin(0.15361853481704) + cos(RADIANS(Entry.longitude)) * cos(0.15361853481704)) - sin(RADIANS(Entry.latitude)) * sin(0.92640848333131))))
AS distance,
(CASE WHEN `Entry`.`title` LIKE '%%' THEN 50 ELSE 0 END +
CASE WHEN `Entry`.`description` LIKE '%%' THEN 30 ELSE 0 END +
CASE WHEN `Entry`.`description_long` LIKE '%%' THEN 10 ELSE 0 END +
CASE WHEN `Entry`.`product_type` = 1 THEN 0 ELSE 0 END +
CASE WHEN `Entry`.`product_type` = 2 THEN 40 ELSE 0 END +
CASE WHEN `Entry`.`product_type` = 3 THEN 50 ELSE 0 END )
AS score,
(CASE WHEN (score > 100 AND distance <= 10) THEN 1 ELSE 0 END)
rank
FROM `usr_web12_1`.`entries` AS `Entry`
inner JOIN `usr_web12_1`.`entrieslocations` AS `Entrieslocation` ON (`Entry`.`id` = `Entrieslocation`.`entry_id`)
inner JOIN `usr_web12_1`.`addresses` AS `Address` ON (`Address`.`id` = `Entry`.`address_id`)
WHERE ((`Entry`.`title` LIKE '%%') OR (`Entry`.`description` LIKE '%%') OR (`Entry`.`description_long` LIKE '%%') OR (`Entry`.`meta_keywords` LIKE '%%') OR (`Entry`.`filter_keywords` LIKE '%%')) AND `Entry`.`status` = 1 AND
`Entry`.`latitude` Between 52.179974594081 AND 53.978617805919 AND `Entry`.`longitude` Between 7.3045938084915 AND 10.298793591508 AND `Entrieslocation`.`category_id` = 1
GROUP BY `Entry`.`id`
ORDER BY `Entry`.`product_type` desc
LIMIT 10
Question: The rank-part doesn't work "Column not found: 1054 Unknown column 'score' in 'field list'", how can I access a dynamic AS-Field???
Same problem with distance...
Thanks a lot!
You can't use an aliased column name in the select or where clause.
You could use it later in the group by, order by, having clause. See the MySQL doc for that.

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