Magento - SQL query programmatically - mysql

I have a SQL query that i would like to write with Magento's collection methods but i don't know how to.
I know that i have to use the getSelect() and joinLeft() methods, but don't know how to put a select inside a left join.
The query is :
SELECT
p.photo_id,
p.photo_name,
s.step_id,
s.step_name
FROM Photo p
LEFT JOIN (
SELECT
photo_id, MAX(step_id) AS max_step_id
FROM photoStep
GROUP BY photo_id
) ps
ON ps.photo_id = p.photo_id
LEFT JOIN Steps s
ON s.step_id = ps.max_step_id

I think that your best option here would be to try to avoid using the subquery. So I would start by reworking the SQL query and then use the functions groupByField & addExpressionFieldToSelect.
->groupByField('photo_id')
->addExpressionFieldToSelect("max_step_id", 'MAX({{step_id}})', 'step_id')

Related

SQL Sub-select statements filter using where clause

I am in the process of building a dashboard and need to extract some data from a somewhat complex schema.
I have a select statement (see below) that I am using to extract information, but need to conduct some filtering on part of the select statement, and I'm struggling.
select distinct j.id 'Job_Id'
, js.outcome 'Outcome'
,(select string from property where parent_sheet_id = ps.id and name= 'Build_Type') as 'Build_Type'
from job j, job_step js, property_sheet ps, property p
where j.id = js.job_id
and ps.entity_id=js.id
and ps.id=p.parent_sheet_id
and ps.entity_type='step'
and p.name = 'Id'
group by j.id
order by j.id desc;
I am sure that there is a better way of doing this query, and I would appreciate any other suggestions, but I am mostly attempting to place a filter on the nested select statement which has an alias of "Build_Type", but when I try it appears not to work. I've read some blogs that this is not possible, so I am a little stuck.
Any help would be much appreciated.
Thanks.
select
ps.id,
Build_Type.string
from
property_sheet as ps
left join
property as Build_Type
on ps.id = Build_Type.parent_sheet_id and Build_Type.name = 'Build_Type'
where Build_Type....

How can I optimize this raw SQL and perhaps implement it via CodeIgniter?

It's been a while since I've written raw SQL, I was hoping someone could help me out in optimizing this SQL query so that it works across, both, MySQL and PostgreSQL.
I would also have to implement this via CodeIgniter (2.x) using ActiveRecord, any help/advice?
SELECT *
FROM notaries, contact_notaries
WHERE notaries.id = contact_notaries.notary_id
AND WHERE ( contact_notaries.city LIKE %$criteria%
OR contact_notaries.state LIKE %$criteria
OR contact_notaries.address LIKE %$criteria%)
Thanks!
Each query can have just one WHERE clause (you don't need the second)
It's much better to put join condition into JOIN rather then WHERE.
Are you sure you really need all the columns from 2 tables (*)?
So I'd refactor it to
SELECT [field_list]
FROM notaries
INNER JOIN contact_notaries ON (notaries.id = contact_notaries.notary_id)
WHERE ( contact_notaries.city LIKE '%$criteria%'
OR contact_notaries.state LIKE '%$criteria'
OR contact_notaries.address LIKE '%$criteria%')
Using a1ex07's query:
SELECT [field_list]
FROM notaries
INNER JOIN contact_notaries ON (notaries.id = contact_notaries.notary_id)
WHERE ( contact_notaries.city LIKE '%$criteria%'
OR contact_notaries.state LIKE '%$criteria'
OR contact_notaries.address LIKE '%$criteria%')
Active record:
$this->db->select(); // Leave empty to select all fields
$this->db->join('contact_notaries', 'notaries.id = contact_notaries.notary_id', 'inner');
$this->db->like('contact_notaries.city', 'criteria');
$this->db->like('contact_notaries.state', 'criteria');
$this->db->like('contact_notaries.address', 'match');
$results = $this->db->get('notaries');
To specify a list of fields you can do $this->db->select('field_1, field_2, ...');.
http://codeigniter.com/user_guide/database/active_record.html

MySQL query - multiple having statements not working

I'm trying to use the following query, and if it only has one having statement it works as expected. If I add the second having statement it does not work.
SELECT candidate.first_name,
candidate.last_name,
qualification.code,
property.value AS funding_band_value,
qualification.funding_band,
property.value AS qualification_level_value,
qualification.qualification_level_id
FROM candidate_qualification, candidate, qualification, property
WHERE candidate_qualification.candidate_id=candidate.id and
candidate_qualification.qualification_id=qualification.id
HAVING funding_band_value = (select property.value from property where qualification.funding_band=property.id) and
HAVING qualification_level_value = (select property.value from property where qualification.qualification_level_id=property.id)
Could someone explain why this doesn't work and how I should do this.
HAVING acts similarly to WHERE or GROUP BY. You reference it once to start using it and combine multiple statements with AND or OR operators. An in depth look at the query parser might give you a more explicit answer.
You don't need HAVING here, just use AND so it is part of your WHERE clause.
The subqueries are not necessary, those tables are already joined.
Something like this should be closer to what you want:
SELECT c.first_name,
c.last_name,
q.code,
p.value AS funding_band_value,
q.funding_band,
p.value AS qualification_level_value,
q.qualification_level_id
FROM candidate_qualification cq
INNER JOIN candidate c ON cq.candidate_id=c.id
INNER JOIN qualification q ON cq.qualification_id=q.id
INNER JOIN property p ON q.funding_band=p.id
and q.qualification_level_id=p.id

MYSQL get other table data in a join

I am currently running this SQL
SELECT jm_recipe.name, jm_recipe.slug
FROM jm_recipe
LEFT JOIN jm_category_recipe ON jm_category_recipe.recipe_id = jm_recipe.id
WHERE jm_category_recipe.category_id = $cat"
This returns the desired results except that I also need to return the name of the category that the recipe I am looking for is in, to do this I tried to add the field in to my SELECT statement and also add the table into the FROM clause,
SELECT jm_recipe.name, jm_recipe.slug, jm_category_name
FROM jm_recipe, jm_category
LEFT JOIN jm_category_recipe ON jm_category_recipe.recipe_id = jm_recipe.id
WHERE jm_category_recipe.category_id = $cat"
However this just returns no results, what am i doing wrong?
You need to join both tables:
SELECT jm_recipe.name, jm_recipe.slug, jm.category_name
FROM jm_recipe
INNER JOIN jm_category_recipe ON jm_category_recipe.recipe_id = jm_recipe.id
INNER JOIN jm_category ON jm_recipe.recipe_id = jm_category.recipe_id
WHERE jm_category_recipe.category_id = $cat
I've changed the joins to inner joins as well. You might want to make them both LEFT joins if you have NULLs and want them in the result.
Also, you're vulnerable to SQL Injection by simply copying over $cat.
Here's some PHP specific info for you (I'm assuming you're using PHP.)

LINQ To SQL "Group By"

I wonder if someone can help me. I want to replicate the following SQL query using LINQ in VB.Net.I'm a little unclear on how to do subqueries / aggregates.
Thanks
SELECT *
FROM Server S
INNER JOIN ServerHDD H
ON S.Server_ID = H.Server_ID
INNER JOIN (SELECT MAX(ServerHDD_ID) AS ServerHDD_ID
FROM ServerHDD
GROUP BY Server_ID, Letter) Filter
ON H.ServerHDD_ID = Filter.ServerHDD_ID
ORDER BY S.Hostname, H.Letter
Got this as below in C# => need VB.Net Conversion please.
from S in SERVER
join H in SERVERHDD on S.Server_ID equals H.Server_ID
join FILTER in
(from s in SERVERHDD group s
by new {s.Server_ID, s.Letter}
into groupedServerHDD select new
{
SERVERHDD_ID = groupedServer.Sum(gS=>gS.ServerHDD_ID)
}
)
on H.ServerHDD_ID equals FILTER.SERVERHDD_ID
orderby S.Hostname, H.Letter
select S
This is my most favorite page regarding this topic. I love LINQ to SQL (and wish they intended to continue support for it over Entity Framework...) http://msdn.microsoft.com/en-us/vbasic/bb688085.aspx. On this page you will find all the answers to your querying needs. It is hard to format the query here without something to test it against!
Your inner joins go away with the simple join syntax of LtS. You can either say .Max() on your inner select or Max(pseudo functoid here) like this:
From p2 In g _
Where p2.UnitPrice = g.Max(Function(p3) p3.UnitPrice) _
Select p2
There are a couple of LINQ learning tools out there that are pretty cool.
This one is my favourite... LinqPad. But you might also want to check out Linqer.
You should be able to paste your code into one of them apps and it will show you how its converted. Hope they come in handy :)