Nested if/else in MySQL select query - mysql

I am having a bit of trouble getting my syntax right for a nested mysql if statement. This is my current query which is fine. But what I need is the parent category. Heres where it confuses me.
Basically I need to add the parentid bit to my query (written in pseudo-code)
SELECT p.*,i.`image`,
( IF(`limitc1`.`parentid` IN (135,136), `limitc1`.parentid)
ELSEIF(`limitc2`.`parentid` IN (135,136), `limitc2`.parentid)
ELSEIF(`limitc3`.`parentid` IN (135,136), `limitc3`.parentid)
ELSEIF(`limitc4`.`parentid` IN (135,136), `limitc4`.parentid)
) as `parentid`
FROM `product` p
JOIN `productcategory` limitpc USING(productid)
LEFT JOIN `category` limitc1 ON (limitpc.`categoryid` = limitc1.`categoryid`)
LEFT JOIN `category` limitc2 ON (limitc1.`parentid` = limitc2.`categoryid`)
LEFT JOIN `category` limitc3 ON (limitc2.`parentid` = limitc3.`categoryid`)
LEFT JOIN `category` limitc4 ON (limitc3.`parentid` = limitc4.`categoryid`)
LEFT JOIN `productlink` l ON (p.`productid` = l.`targetid` OR p.`productid` = l.`sourceid`)
JOIN `productimage` i ON p.`productid` = i.`productid` AND i.`primary` = 1
WHERE (l.`sourceid` = 5471 OR l.`targetid` = 5471)
AND p.`visible` = 1
AND p.`websitevisible` = 1
AND p.`productid` != 5471
GROUP BY p.`productid`
LIMIT 8
Any ideas would be greatly appreciated! :-)

You want to use the case statement:
SELECT p.*,i.`image`,
(case when `limitc1`.`parentid` IN (135,136) then `limitc1`.parentid
when `limitc2`.`parentid` IN (135,136) then `limitc2`.parentid
when `limitc3`.`parentid` IN (135,136) then `limitc3`.parentid
when `limitc4`.`parentid` IN (135,136) then `limitc4`.parentid
end) as `parentid`
. . .
Not only does this do what you want to do, but it is also standard SQL. The if statement is specific to MySQL.

Related

How create multiplies select with inner join in Ruby on Rails?

I want create that query
SELECT * FROM `books` INNER JOIN (SELECT * FROM `authors` GROUP by `author_id`) as variable ON variable.`id` = `books`.`id` INNER JOIN `student` ON `student`.`id` = variable.`id` WHERE (`books`.`id` = '1');
For the question, of course, the request itself is slightly changed, but that's not the point. Can you please help me to make this kind of request in Ruby on Rails style
I tried, but it's a bit not what I want ... I have to do INNER JOIN (Select ... )
Book.select('*').joins(author: :student).where("`books`.`id` = '1'").group("author.author_id")
While your SQL does not appear to make any logical sense you can construct this query as follows:
author_table = Author.arel_table
author_sub_query = Arel::Nodes::TableAlias.new(
author_table
.project(author_table[Arel.star])
.group(author_table[:author_id]), 'variable')
author_join = Arel::Nodes::InnerJoin.new(
author_sub_query,
author_sub_query.create_on(author_sub_query[:id].eq(Book.arel_table[:id])))
student_join = Arel::Nodes::InnerJoin.new(
Student.arel_table,
author_sub_query.create_on(Student.arel_table[:id].eq(author_sub_query[:id])))
Book
.select(Arel.star)
.joins(author_join,student_join)
.where(id: 1)
Which will produce:
SELECT
*
FROM
`books`
INNER JOIN (SELECT `authors`.* FROM `authors` GROUP BY `authors`.`author_id`) `variable`
ON `variable`.`id` = `books`.`id`
INNER JOIN `students`
ON `students`.`id`= `variable`.`id`
WHERE
`books`.`id` = 1
That being said I have no idea what you are trying to do with this but if the intent is to eager load this data, you could try making these changes to the above:
author_sub_query = Arel::Nodes::TableAlias.new(
author_table
.project(author_table[Arel.star])
.group(author_table[:author_id]), Author.table_name)
Book
.joins(author_join,student_join)
.eager_load(author: :student)
.where(id: 1)

Problems Summing up result of MySQL query

The following query returns what is displayed in the attached image.
What I thought would be very simple has turned out to be very complex. All I simply want to do is now total up the result into one row and column. In this case the sum would be 161. How do I do this? I've literally tried everything. I hope I've provided enough information.
SELECT
TRUNCATE
(
SUM(
`assignment`.`percentage_achieved` *(
SELECT
`unitComponentWeighting`.`percentage_weighting` / 100
FROM
`unitComponentWeighting`
WHERE
`assignment`.`assignment_component_id` = `unitComponentWeighting`.`component_lookup_id`
LIMIT 1
)
),
2
) AS `unit_percentage_grade`
FROM
`assignment`
LEFT JOIN `assignmentType` ON `assignment`.`assignment_type_id` = `assignmentType`.`id`
LEFT JOIN `assignmentComponentLookup` ON `assignmentComponentLookup`.`id` = `assignment`.`assignment_component_id`
LEFT JOIN `unit` ON `unit`.`id` = `assignment`.`unit_id`
LEFT JOIN `assignmentSequence` ON `assignmentSequence`.`id` = `assignment`.`assignment_sequence_id`
LEFT JOIN `yearGroup` ON `yearGroup`.`id` = `unit`.`year_group_id`
WHERE
`yearGroup`.`id` = 1
GROUP BY
`assignment`.`unit_id`
try removing this part
" GROUP BY
assignment.unit_id "

Mysql row query to codeigniter query

I have the following Mysql query. Running as needed.
SELECT
t_doc.*, t_user.IDA, t_data.IDA
FROM
( SELECT DISTINCT IDau FROM t_doc ) IDau_list
LEFT OUTER JOIN
(
SELECT
IDd ,IDau
FROM
t_doc
WHERE
doc_type = 'doc'
GROUP BY IDau
)
doc_images ON doc_images.IDau = IDau_list.IDau
LEFT OUTER JOIN
(
SELECT
IDd ,IDau
FROM
t_auto_doc
WHERE
doc_type = 'jpg'
GROUP BY IDau
)
jpg_images ON jpg_images.IDau = IDau_list.IDau
LEFT OUTER JOIN
t_doc ON t_doc.IDdoc = COALESCE(jpg_images.IDd, doc_images.IDd)
LEFT OUTER JOIN
t_user ON t_user.IDau = t_doc.IDau
LEFT OUTER JOIN
t_data ON t_user.IDA = t_data.IDA
But, What I must bring this query to codeigniter Model, in which I have to adapt the query, as example like this...
$this->db->select('u.IDau, a.*');
$this->db->from('t_user u');
$this->db->join('t_doc d', 'd.IDau=u.IDau', 'left');
And ...More.....Here......
But, I got it difficult. Is some one out there might change it Please..
Thanks in advance
As #NEVERMIND Suggest I have accomplish the task using...
$query = $this->db->query("My QUERY WITH A BIT OF CHANGE");
Yes, I should make some change to get the exact Data as i needed.
Thanks for all of your comments and ideas.

MySQL How to check if an value is already in the results?

I've got a complicated problem.
How can I force MySQL to replace the first "command.deagle2" (Mode 1) with the second "command.deagle2" (Mode 0) ?
I simply show you the code and I hope you can help me.
Here my code:
SELECT DISTINCT
`right`.`name` AS `Right`,
1 AS `Mode`
FROM
`user`
INNER JOIN
`user_group` ON
`user`.`id` = `user_group`.`user_id`
INNER JOIN
`group` ON
`user_group`.`group_id` = `group`.`id`
INNER JOIN
`group_right` ON
`group`.`id` = `group_right`.`group_id`
INNER JOIN
`right` ON
`group_right`.`right_id` = `right`.`id`
WHERE
`user`.`username` = 'Dominik'
UNION
SELECT DISTINCT
`right`.`name` AS `Right`,
`user_right`.`mode` AS `Mode`
FROM
`user`,
`right`,
`user_right`
WHERE
`user`.`id` = `user_right`.`user_id` AND
`right`.`id` = `user_right`.`right_id` AND
`user`.`username` = 'Dominik'
This query returns the following results:
Right | Mode
-----------------------
command.deagle | 1
command.deagle2 | 1
command.gmx | 1
command.givegun | 1
command.deagle2 | 0
Sample dataset: http://pastebin.com/m5LHsDRi
I already saw that there is an REPLACE keyword, but I dont really know how to use it properly.
Thanks for your Time.
Dominik
I take it your "mode" column constitutes a priority, and you want the only the distinct value of "Right" with the lowest-numbered priority in your result set.
Try wrapping this query around the query you gave us:
SELECT Right,
MIN(Mode) AS Mode,
FROM (
/* your big query */
) AS q
GROUP BY Right
That will give you what you want. By the way, you can remove the DISTINCT keyword from your main query if you do this; the GROUP BY will fill the same purpose.

How can I update where a given select condition returns a true value?

I want to perform an SQL update
UPDATE incCustomer SET etaxCode = 'HST' WHERE
only on records where this is true.
select etaxCode
from incCustomer
left join incAddress on incCustomer.iAddressId = incAddress.iId
left join incProvince on incAddress.iProvinceStateId = incProvince.iId
where incAddress.iProvinceStateId in ( 2 , 3 , 4 , 6 , 9 )
I don't think that this is possible with ANSI SQL, but can it be done in MySQL?
MySQL UPDATE syntax supports joins in both ANSI-89 and ANSI-92 syntax.
Use:
UPDATE INCCUSTOMER c
LEFT JOIN INCADDRESS a ON a.iid = c.iaddressid
LEFT JOIN INCPROVINCE p ON p.iid = a.iprovincestateid
SET c.etaxcode = 'HST'
WHERE a.iProvinceStateId IN (2,3,4,6,9)
I don't see the point of LEFT JOINing to the province table - I think your UPDATE could be written as:
UPDATE INCCUSTOMER
SET c.etaxcode = 'HST'
WHERE EXISTS(SELECT NULL
FROM INCADDRESS a
WHERE a.iid = INCCUSTOMER.iaddressid
AND a.iProvinceStateId IN (2,3,4,6,9))