DRUPAL db_or adding AND between multiple variables - sql

I have inherited an application that is using the drupal filtering system to find results. The user can select to search the 'campus_location' column but when they enter multiple variables, it adds an AND between the condition.
Here is the printed version of the query generated by drupal:
SELECT * FROM champs c INNER JOIN users u ON u.uid = c.uid LEFT OUTER JOIN champs_rsvp r
ON r.uid = c.uid LEFT OUTER JOIN champs_checklists cl
ON cl.id = c.checklist_id LEFT OUTER JOIN node en
ON en.uid = u.uid AND en.type = 'getting_started_event'
LEFT OUTER JOIN node sn ON sn.uid = u.uid
AND sn.type = 'success_story'
LEFT OUTER JOIN champs_action_steps cas
ON cas.uid = u.uid
WHERE ( (c.campus_location LIKE 'Flint' ESCAPE '\\') )
**AND**( (c.campus_location LIKE 'Ann Arbor' ESCAPE '\\') )
I need the last AND to be an OR so it looks like this:
SELECT * FROM champs c INNER JOIN users u ON u.uid = c.uid LEFT OUTER JOIN champs_rsvp r
ON r.uid = c.uid LEFT OUTER JOIN champs_checklists cl
ON cl.id = c.checklist_id LEFT OUTER JOIN node en
ON en.uid = u.uid AND en.type = 'getting_started_event'
LEFT OUTER JOIN node sn ON sn.uid = u.uid
AND sn.type = 'success_story'
LEFT OUTER JOIN champs_action_steps cas
ON cas.uid = u.uid
WHERE ( (c.campus_location LIKE 'Flint' ESCAPE '\\') )
OR( (c.campus_location LIKE 'Ann Arbor' ESCAPE '\\') )
Which produces the correct results.
Here is the code that I inherited where it looks over the words in the search box. I just can't seem to figure out where it is adding the variables where it is putting the AND.
$words = explode(",", $_SESSION['form_state']['values']['filter']);
foreach($words as $word)
{
$or = db_or();
foreach($cols as $col)
{
$table = 'c';
if(in_array($col, array('completed_date', 'score')))
$table = 'cl';
elseif(in_array($col, array('name', 'mail')))
$table = 'u';
elseif($col == 'date')
$table = 'r';
elseif(in_array($col, array('announce', 'num_success_stories', 'num_action_steps'))) //can't put these in WHERE clause. Need to go in HAVING.
continue;
echo $word;
$or = $or->condition($table . '.' . $col, champs_make_like_sql($word), 'LIKE');
}
$result = $query->condition($or);
}

Related

Querying in Entity Framework

I need to translate that query to Entity Framework, can someone help me ?
select distinct
rap.AtracacaoData Atracacao,
loc.Nome_Local Local,
nav.Nome Navio,
nav.Navio_ID ViagemNavio,
'DT ' TransferenciaTipo,
edt.Numero TransferenciaNumero,
loct.Local Terminal
from
terminal..blalf bl (nolock)
inner join
terminal..navios nav (nolock) on nav.navio_id = bl.navio
inner join
terminal..avisochegada rap (nolock) on rap.Numero_Viagem_Ano = nav.Viagem_Ano_AVC
inner join
terminal..localatracalf loc (nolock) on loc.codigo_local = rap.armazem
inner join
tresos..vw_autorizacaorecebimento_navio autnav (nolock) on autnav.viagemnavio = nav.navio_id
and autnav.tipo = 2
inner join
tresos..edt edt (nolock) on edt.ID = autnav.DeclaracaoTransitoEntrada
inner join
tresos..localidades loct (nolock) on loct.ID = bl.terminal
union
select distinct
rap.AtracacaoData Atracacao,
loc.Nome_Local Local,
nav.Nome Navio,
nav.Navio_ID ViagemNavio,
'DTA ' TranferenciaTipo,
edt.Numero TransferenciaNumero,
loct.Local Terminal
from
terminal..blalf bl (nolock)
inner join
terminal..navios nav (nolock) on nav.navio_id = bl.navio
inner join
terminal..avisochegada rap (nolock) on rap.Numero_Viagem_Ano = nav.Viagem_Ano_AVC
inner join
terminal..localatracalf loc (nolock) on loc.codigo_local = rap.armazem
inner join
tresos..vw_autorizacaorecebimento_navio autnav (nolock) on autnav.viagemnavio = nav.navio_id
and autnav.tipo = 3
inner join
tresos..edta edt (nolock) on edt.ID = autnav.DeclaracaoTransitoEntrada
inner join
tresos..localidades loct (nolock) on loct.ID = bl.terminal
union
select distinct
rap.AtracacaoData Atracacao,
loc.Nome_Local Local,
nav.Nome Navio,
nav.Navio_ID ViagemNavio,
'PCI ' TranferenciaTipo,
edt.Numero TransferenciaNumero,
loct.Local Terminal
from
terminal..blalf bl (nolock)
inner join
terminal..navios nav (nolock) on nav.navio_id = bl.navio
inner join
terminal..avisochegada rap (nolock) on rap.Numero_Viagem_Ano = nav.Viagem_Ano_AVC
inner join
terminal..localatracalf loc (nolock) on loc.codigo_local = rap.armazem
inner join
tresos..vw_autorizacaorecebimento_navio autnav (nolock) on autnav.viagemnavio = nav.navio_id
and autnav.tipo = 4
inner join
tresos..eprc edt (nolock) on edt.ID = autnav.DeclaracaoTransitoEntrada
inner join
tresos..localidades loct (nolock) on loct.ID = bl.terminal
I tried to do but I couldn't do it.
First, you need an Entity Framework model that maps to your SQL structure. Hopefully you already have that. I'm assuming you do.
Second, you should create a DTO that has the properties your query will return:
public class ASensibleNameInYourDomain {
public ? Atracaco {get; set;}
public string Local {get; set;}
...
}
Third, you write a function that takes your EF DbContext and the query params, and returns a list of your DTO. It looks like your SQL is the same query repeated so I'd do:
public List<ASensibleNameInYourDomain> LoadFlightInfo(DbContext context, int autNavTipo, string transfericaTipo) {
return context.Blalf.Select(blaf=>
new ASensibleNameInYourDomain {
Atracacao=blaf.Navios.Avisochegada.AtracacaoData,
Local=blaf.Navios.Avisochegada.Localatracalf.Nome_Local,
Navio=blaf.Navios.Nome,
ViagemNavio=blaf.Navios.Navio_ID,
TransferenciaTipo=transfericaTipo,
TransferenciaNumero=blaf.Navios.Autorizacaorecebimento_navio.Numero,
Terminal=blaf.Localidades.Local
}
).Where(blaf=> blaf.Navios.Autorizacaorecebimento_navio.Tipo == autNavTipo)
.Distinct()
.ToList()
}
And then call it like so
public List<ASensibleNameInYourDomain> GetFlights(DbContext context) {
var result = LoadFlightInfo(context, 2, "DT");
result.addRange(LoadFlightInfo(context, 3, "DTA"));
result.addRange(LoadFlightInfo(context, 4, "PCI"));
return result
}
I think that'll do it, been a while since I did any C#...

Increase query performance in wp_posts, via wp_get_nav_menu_items using custom sql query in wordpress

Today I ran into a problem that noticeably slows down the performance of the site. In my header, menu categories are loaded (menu name -> header_nav). I load them with a function like wp_get_nav_menu_items ($ menu-> term_id). This function returns an array of objects in which there are a lot of fields, since there are a lot of categories, there are also a lot of objects. From the whole object, I need only $ object-> title, $ object-> link, $ object-> id. I need to get this data from multilingual titles.
//$menu_items too large array of objects
$menu = wp_get_nav_menu_object( $locations[ 'menu_slug'] );
//Here my array. do foreach and creating category menu using
//$menu_item->title...and etc.
$menu_items = wp_get_nav_menu_items($menu->term_id);
And I decided to write my own request. But it returns data without multilingual
SELECT p2.ID, p2.post_title, p2.post_name, p2.guid,
p1.post_parent
FROM wp_posts p1
INNER JOIN wp_term_relationships AS TR
ON TR.object_id = p1.ID
INNER JOIN wp_postmeta AS pm
ON pm.post_id = p1.ID
INNER JOIN wp_posts AS p2
ON p2.ID = pm.meta_value
WHERE p1.post_type = 'nav_menu_item'
AND TR.term_taxonomy_id = $taxId
AND pm.meta_key = '_menu_item_object_id'
ORDER BY p1.menu_order ASC
How to return already translated titles?
SELECT * FROM wp_posts p1 INNER JOIN wp_term_relationships AS TR ON TR.object_id =
p1.ID INNER JOIN wp_postmeta AS PM ON pm.post_id = p1.ID INNER JOIN wp_posts AS p2 ON
p2.ID = PM.meta_value WHERE p1.post_type = 'nav_menu_item' AND TR.term_taxonomy_id = (
SELECT wp_terms.term_id FROM wp_terms WHERE slug = 'pedik') AND pm.meta_key =
'_menu_item_object_id' ORDER BY p1.menu_order ASC
for title
$menu_item->object_id = ! isset( $menu_item->object_id ) ? get_post_meta(
$menu_item-
>ID, '_menu_item_object_id', true ) : $menu_item->object_id;
for url
$menu_item->url = get_permalink( $menu_item->object_id );
for title
$original_title = apply_filters( 'the_title', $original_object-
>post_title,$original_object->ID );
if ( '' === $original_title ) {
/* translators: %d: ID of a post */
$original_title = sprintf( __( '#%d (no title)' ), $original_object-
>ID );
}
$menu_item->title = '' == $menu_item->post_title ? $original_title :
$menu_item->post_title;

How can I perform a left join and exclude results that match a subquery in LINQ?

Need to convert this sql query to LINQ
SELECT *
FROM
parcels p
LEFT JOIN leases l ON p.parcels_pk = l.parcels_fk
WHERE
l.parcels_fk IS NULL
AND p.parcels_pk NOT IN (SELECT parcels_fk FROM application_parcels)
ORDER BY parcel
tried this:
var qry = from p in db.Parcels
join l in db.Leases on p.Id equals l.pk_parcel
where l.pk_parcel == null
&& !(from ap in db.ApplicationParcels
select ap.ParcelId).Contains(p.Id)
orderby p.Name
// SELECT * FROM parcels
var result = from p in parcels
// LEFT JOIN leases ON p.parcels_pk = l.parcels_fk
join llj in leases on p.parcels_pk equals llj.parcels_fk into lj
from l in lj.DefaultIfEmpty()
// WHERE l.parcels_fk IS NULL
where l.parcels_fk == null
// AND p.parcels_pk NOT IN (...)
&& !application_parcels.Any(x => x.parcels_fk == p.parcels_pk)
// ORDER BY [p.]parcel
order by p.parcel
select new { parcel = p, lease = l };
Assuming i have your schema correct.
But in the future:
First supply what you've tried (show an effort).
Have a look at LINQPad, it's very helpful.

Complex SQL to LINQ conversion with subquery

I am trying to convert this expression into LINQ from SQL, but a bit too difficult for me, maybe you can help me with this!
SELECT TOP (2) RecipeID, UserID, Name, Servings, PreparationTime, TotalTime, DifficultyLevelID, CuisineID, DishID, MainIngredientID, PriceLevelID, FlavourID, Instructions,
Notes, Thumbnail, VideoLink
FROM dbo.Recipes
WHERE (RecipeID NOT IN
(SELECT DISTINCT Recipes_1.RecipeID
FROM dbo.Allergies INNER JOIN
dbo.UsersAllergies ON dbo.Allergies.AllergyID = dbo.UsersAllergies.AllergyID INNER JOIN
dbo.IngredientsAllergies ON dbo.Allergies.AllergyID = dbo.IngredientsAllergies.AllergyID INNER JOIN
dbo.Ingredients ON dbo.IngredientsAllergies.IngredientID = dbo.Ingredients.IngredientID INNER JOIN
dbo.RecipesIngredients ON dbo.Ingredients.IngredientID = dbo.RecipesIngredients.IngredientID INNER JOIN
dbo.Recipes AS Recipes_1 ON dbo.RecipesIngredients.RecipeID = Recipes_1.RecipeID INNER JOIN
dbo.Users ON dbo.UsersAllergies.UserID = dbo.Users.UserID INNER JOIN
dbo.AllergyFactors ON dbo.IngredientsAllergies.AllergyFactorID = dbo.AllergyFactors.AllergyFactorID
WHERE (dbo.Users.UserID = 3) AND (dbo.AllergyFactors.AllergyFactorID < 3)))
It would be easier to help you if you showed us what you have already tried, but a Linq expression like this should give you the same result set
var query = (from rec in context.Recipes
where !(from al in context.Allergies
from ua in context.UsersAllergies.Where(x => al.AllergyID == x.AllergyID)
from ia in context.IngredientsAllergies.Where(x => al.AllergyID == x.AllergyID)
from in in context.Ingredients.Where(x => ia.IngredientID == x.IngredientID)
from ri in context.RecipesIngredients.Where(x => in.IngredientID == x.IngredientID)
from re in context.Recipes.Where(x => ri.RecipeID == x.RecipeID)
from us in context.Users.Where(x => ua.UserID == x.UserID)
from af in context.AllergyFactors.Where(x => ia.AllergyFactorID == x.AllergyFactorID)
where us.UserID == 3 && af.AllergyFactorID < 3
select re.RecipeID)
.Distinct()
.Contains(rec.RecipeID)
select new
{
rec.RecipeID,
rec.UserID,
rec.Name,
rec.Servings,
rec.PreparationTime,
rec.TotalTime,
rec.DifficultyLevelID,
rec.CuisineID,
rec.DishID,
rec.MainIngredientID,
rec.PriceLevelID,
rec.FlavourID,
rec.Instructions,
rec.Notes,
rec.Thumbnail,
rec.VideoLink
}).Take(2);

Zend how do I create a left join

How do I turn this left join query:
select advertisercontest.*, advertiseraccount.advertiserid, advertiseraccount.companyname
from advertisercontest
left join advertiseraccount on advertiseraccount.loginid = advertisercontest.loginid
where advertisercontest.golive is not NULL;
into a left join in Zend?
You could do as follows:
$db = Zend_Db_Table::getDefaultAdapter();
$select = $db->select();
$select->from('advertisercontest', '*')
->joinLeft(
'advertiseraccount',
'advertiseraccount.loginid = advertisercontest.loginid',
array('advertiseraccount.advertiserid', 'advertiseraccount.companyname')
)
->where('advertisercontest.golive is not NULL');;
$result = $db->fetchAll($select);
var_dump($result);
Here is the Zend_Db_Select documentation.