Drupal performing a query against the database - drupal

I wish to retrieve some nids from my drupal database. I have a query that I wish to run.
SELECT node.nid AS projectnid
FROM node node
INNER JOIN content_type_project node_data_field_project_client ON node.vid = node_data_field_project_client.vid
WHERE node_data_field_project_client.field_project_client_nid = (SELECT node_data_field_profile_company.field_profile_company_nid AS company_nid
FROM node node LEFT JOIN content_type_profile node_data_field_profile_company ON node.vid = node_data_field_profile_company.vid WHERE node.nid = 218)
I am calling the query by using:
$query =
"
SELECT node.nid AS projectnid
FROM node node
INNER JOIN content_type_project node_data_field_project_client ON node.vid = node_data_field_project_client.vid
WHERE node_data_field_project_client.field_project_client_nid = (SELECT node_data_field_profile_company.field_profile_company_nid AS company_nid
FROM node node LEFT JOIN content_type_profile node_data_field_profile_company ON node.vid = node_data_field_profile_company.vid WHERE node.nid = 218)
";
$result = db_query($query);
dsm($result);
The dsm is giving me an empty object. When I run the SQL directly I get back a result.
So my question would be how would you get db_query to return you all your results as an object (I don't really mind if an object or array).
(The SQL was created by looking at the query output for views.)
This is a follow up to question: Drupal Views Relationships and Arguments
I have a Person content type. It has a
node reference field of a company
which is also a content type. I then
have a content type called Project. A
project has a node reference to a
company content type. I want to list
all the projects related to a person
id (nid)id (nid)

The following works:
$query =
"
SELECT node.nid AS projectnid
FROM node node
INNER JOIN content_type_project node_data_field_project_client ON node.vid = node_data_field_project_client.vid
WHERE node_data_field_project_client.field_project_client_nid = (SELECT node_data_field_profile_company.field_profile_company_nid AS company_nid
FROM node node LEFT JOIN content_type_profile node_data_field_profile_company ON node.vid = node_data_field_profile_company.vid WHERE node.nid = 218)
";
$results = db_query($query);
while ($result = db_result($results)) {
dsm($result);
}
You need to use db_result() to get the results out. Worked this out by using http://drupal.org/node/259432#comment-846946

Related

Complex AX Query

i want to rebuild this SQL Query as AX Query.
I tried it in several ways, but I don't get it.
I am not completely new to AX queries, but I only have experience with some simple queries not with such complex SQL queries.
SELECT * FROM ( SELECT DH.[RECID] AS RECID_DIMENSIONHIERARCHY
,DH.[NAME] AS NAME__DIMENSIONHIERARCHY
,DH.[DESCRIPTION] AS DESC__DIMENSIONHIERARCHY
,DH.[PARTITION] AS PARTITION_DIMENSIONHIERARCHY
,DL.[DIMENSIONATTRIBUTE] AS RECID_DIMENSIONATTRIBUTE
,DA.[NAME] AS NAME_DIMENSIONATTRIBUTE
,DN.[RECID] AS RECID_DIMENSIONCONSTRAINTNODE
,DNC.[RECID] AS RECID_DIMENSIONCONSTRAINTNODECRITERIA
,DNC.[RANGETO] AS #Owner
,DNCR.[WILDCARDSTRING] AS #Agreement
FROM (SELECT * FROM [dbo].[DIMENSIONHIERARCHY]
WHERE [STRUCTURETYPE] = 1 AND [NAME] LIKE 'AG-OW%'
) AS DH
INNER JOIN [dbo].[DIMENSIONHIERARCHYLEVEL] AS DL
ON DH.[RECID] = DL.[DIMENSIONHIERARCHY]
AND DH.[PARTITION] = DL.[PARTITION]
INNER JOIN [dbo].[DIMENSIONATTRIBUTE] AS DA
ON DL.[DIMENSIONATTRIBUTE] = DA.[RECID]
AND DL.[PARTITION] = DA.[PARTITION]
INNER JOIN [dbo].[DIMENSIONCONSTRAINTNODE] AS DN
ON DL.[RECID] = DN.[DIMENSIONHIERARCHYLEVEL]
AND DL.[PARTITION] = DN.[PARTITION]
INNER JOIN [dbo].[DIMENSIONCONSTRAINTNODECRITERIA] AS DNC
ON DN.[RECID] = DNC.[DIMENSIONCONSTRAINTNODE]
AND DN.[PARTITION] = DNC.[PARTITION]
INNER JOIN [dbo].[DIMENSIONCONSTRAINTNODECRITERIA] AS DNCR
ON DN.[PARENTCONSTRAINTNODE] = DNCR.[DIMENSIONCONSTRAINTNODE]
AND DN.[PARTITION] = DNCR.[PARTITION]
) AS Sub
You need to break down your query and implement it in small chunks. Then combine all of it to get the desired result.
There are two ways to create query in X++.
Create query using select statement for example:
Select * from HcmWorker join * from DirPerson
where DirPerson.RecId == HcmWorker.Person
See this link : Select statement syntax
Create query with AOT structure. You might want to have a look at the following link:
Create query in AOT by using X++

How to select specific properties of properties through DQL

I have the following Entities. First and foremost: the design derived from a legacy DB and it has been semplified here for clarity shake.
What I would like to do is selecting all the widgets along with their varsSelection populated (in this very moment Widget only contains PhyVarSelection instances so we can focus on them) which should have teir phyVar hydrated. Phyvar must not be populated with its ewCfgVar property.
I'm trying to do it by using DQL. I succeeded to select all the widgets and their relative varsSelection, but I'm not able to populate their relative phyVar. Is that possible? Here is the DQL I'm using:
$sql = <<<EOS
SELECT wid, partial phyvarsel.{id, phyVar, start}
FROM Belka\\TsBundle\\Entity\\Widget wid
LEFT JOIN Belka\\TsBundle\\Entity\\PhyVarSelection phyvarsel WITH wid.id = phyvarsel.widget
LEFT JOIN Belka\\TsBundle\\Entity\\PhyVar phyvar WITH phyvarsel.phyVar = phyvar.id
EOS;
$query = $this->getEntityManager()->createQuery($sql);
If I dump the result, Widget and varsSelection are correctly populated, but PhyVarSelection::phyVar is set to NULL.
The query DQL it generates is actually correct, and if I query it I get all the PhyVar's properties:
die(var_dump($query->getSQL()));
It generates:
SELECT a0_.id AS id0, a0_.title AS title1, a0_."order" AS order2, a0_.span_cols AS span_cols3, a0_.description AS description4, a1_.id AS id5, a1_.start AS start6, a2_.id AS id7, a0_.part_of_section AS part_of_section8, a1_.vartype AS vartype9, a1_.part_of_widget AS part_of_widget10, a1_.phy_var_sel AS phy_var_sel11, a2_.vartype AS vartype12, a2_.part_of_phy_meter AS part_of_phy_meter13, a2_.varname AS varname14, a2_.id_device AS id_device15 FROM app_t.widget a0_ LEFT JOIN app_t.var_selection a1_ ON (a0_.id = a1_.part_of_widget) AND a1_.vartype IN ('phy') LEFT JOIN app_t.variable a2_ ON (a1_.phy_var_sel = a2_.id) AND a2_.vartype IN ('phy');
I don't paste here the Entities' code but if you need it let me know with a comment below and I will update the question.
Update
I've also tried the following:
$sql2 = <<<EOS
SELECT phyvarsel, phyvar
FROM Belka\\TsBundle\\Entity\\PhyVarSelection phyvarsel
LEFT JOIN Belka\\TsBundle\\Entity\\PhyVar phyvar
WHERE phyvarsel.id = :phyvarselid
EOS;
$query2 = $this->getEntityManager()->createQuery($sql2);
$query2->setParameter('phyvarselid', '0');
$query2->setHint(Query::HINT_FORCE_PARTIAL_LOAD, true);
$varSel = $query2->getResult();
again, in this case I get PhyVarSelection but its attribute phyVar is still set to NULL.

Querying 2/3 tables with one SQL statement

I have three tables: users, projects, user_project
user_project contains user_id, project_id and role_id, where user_id and project_id are both primary keys connected to projects.project_id and users.user_id.
I want to get the the name and surname of all the users from the users table that has to do with a certain project from the projects table through user_project.
What SQL statement do I have to use? I was thinking something like this:
SELECT
users.name, users.surname
FROM users
WHERE users.user_id = user_project.user_id AND projects.project_id = #parameter
I am using SQL Server 2012 and ASP.NET/VB.NET.
Db Diagram:
http://i.imgur.com/lrv52wO.png
SELECT users.name, users.surname
FROM users u
INNER JOIN user_project up
ON u.user_id = up.user_id
WHERE up.project_id = #parameter
You'll need to join to your other tables - either from Users through User_Project all the way to Projects if you want to base your selection on something in the Projects table:
SELECT
u.name, u.surname
FROM users u
INNER JOIN user_project up ON u.user_id = up.user_id
INNER JOIN project p ON p.project_id = up.project_id
WHERE p.project_name = 'something'
or at least to the link table, if you can use the project_id as criteria:
SELECT
u.name, u.surname
FROM users u
INNER JOIN user_project up ON u.user_id = up.user_id
WHERE up.project_id = #parameter
Update: assuming your Role table is connected to Users through again a link table Users_role then you need this to select role name, too:
SELECT
u.name, u.surname,
RoleName = r.Name
FROM users u
INNER JOIN user_project up ON u.user_id = up.user_id
INNER JOIN user_roles ur ON u.user_id = ur.user_id
INNER JOIN role r ON ur.role_id = r.role_id
WHERE up.project_id = #parameter
SELECT
users.name, users.surname
FROM users
inner join user_project
on users.user_id = user_project.user_id
WHERE user_project.project_id = #parameter
This should do it.
SELECT users.name, users.surname
FROM users
INNER JOIN user_project ON user_project.user_id = users.user_id
WHERE (user_project.project_id = #parameter)
The important line here is the line that starts INNER JOIN. You don't need the project table as the project_id column is in user_project. If you wanted to get the project name for example you would need the project table. You would do this by writing another INNER JOIN.
INNER JOIN project ON project.project_id = user_project.project_id
Now that you have joined you can access all the columns in the project table.

Symfony2 Doctrine SQL object mapping on subselect

I'm trying to use this query:
MySQL SELECT DISTINCT by highest value
SELECT
p.*
FROM
product p
INNER JOIN
( SELECT
magazine, MAX(onSale) AS latest
FROM
product
GROUP BY
magazine
) AS groupedp
ON groupedp.magazine = p.magazine
AND groupedp.latest = p.onSale ;
Within Symfony2 and DQL.
I have:
$query = $em->createQuery("SELECT p FROM MyBundle:Product p WHERE p.type = 'magazine' AND p.maglink IS NOT NULL OR (p.type = 'magazine' AND p.diglink IS NOT NULL) GROUP BY p.magazine ORDER BY p.onSale DESC");
Which works fine with and outputs objects but without the correct MAX(onSale)
Doing:
$query = $em->createQuery("SELECT p , MAX(p.onSale) FROM MyBundle:Product p WHERE p.type = 'magazine' AND p.maglink IS NOT NULL OR (p.type = 'magazine' AND p.diglink IS NOT NULL) GROUP BY p.magazine ORDER BY p.onSale DESC");
Results in non-objects being returned.
This:
$query = $em->createQuery("SELECT
p.*
FROM
MyBundle:Product p
INNER JOIN
( SELECT
p.magazine, MAX(onSale) AS p.latest
FROM
MyBundle:Product p
GROUP BY
p.magazine
) AS groupedp
ON groupedp.magazine = p.magazine
AND groupedp.latest = p.onSale ;");
Throws this error:
[Semantical Error] line 0, col 127 near 'SELECT
': Error: Identification Variable ( used in join path expression but was not defined before.
I assume due to this Symfony2 Doctrine query
How can I maintain my mapping while still being able to sort each item by onsale?
Have you considered splitting this into two queries:
First:
Run your query directly against the database connection, and return the IDs of the relevant rows, in the order you want. This separates your complex query from DQL.
Second:
Query the rows through Doctrine to get the full entities you want, based on the IDs/orders of the previous query.
This is a shot in the dark, but it seems fairly obvious. Your aliasing two tables to the same alias. Thus when your using p. in the join it thinks your working from the original definition of p from before the join, then you alias the join as p. Change the alias of the join (and the references to that table) so each alias is unique.

NHibernate Collection Left Outer Join Where Clause Issue

It seems that when using the following NHibernate query, I do not get a root entity when the left outer join has no records.
ICriteria critera = session.CreateCriteria(typeof(Entity));
criteria.CreateCriteria("SubTable.Property", "Property", NHibernate.SqlCommand.JoinType.LeftOuterJoin);
criteria.Add(Expression.Not(Expression.Eq("Property", value)));
The SQL that I am trying to generate is:
SELECT * FROM BaseTable
LEFT JOIN (
SELECT * FROM SubTable
WHERE Property <> value
)Sub ON Sub.ForeignKey = BaseTable.PrimaryKey
Notice that the where clause is inside the left join's select statement. That way if there arent any maching sub records, we still get a top level record. It seems like NHibernate is producing the following SQL.
SELECT * FROM BaseTable
LEFT JOIN (
SELECT * FROM SubTable
)Sub ON Sub.ForeignKey = BaseTable.PrimaryKey
WHERE Sub.Property <> value
Is there anyway to achieve that first piece of SQL? I have already tried:
ICriteria critera = session.CreateCriteria(typeof(Entity));
criteria.CreateCriteria("SubTable.Property", "Property", NHibernate.SqlCommand.JoinType.LeftOuterJoin);
criteria.Add(
Restrictions.Disjunction()
.Add(Expression.IsNull("Property"))
.Add(Expression.Not(Expression.Eq("Property", value)));
I am looking for a solution using the Criteria API.
Try this:
var hql = #"select bt
from BaseTable bt
left join bt.SubTable subt
with subt.Property <> :property";
Or perhaps:
var hql = #"select bt
from BaseTable bt
left join bt.SubTable subt
where subt.ForeignKey = bt.PrimaryKey
and subt.Property <> :property";
Finally:
var result = session.CreateQuery(hql)
.SetParameter("property", "whateverValue")
.List<BaseTable>();
I don't use nHibernate but I think this is the SQL you need to generate:
SELECT *
FROM BaseTable
LEFT JOIN SubTable sub
ON Sub.ForeignKey = BaseTable.PrimaryKey and sub.Property <> value
What you want isn;t a where clasue but an additional condition on the join. Hope that helps.

Resources