Query for articles in drupal 7 - mysql

I need a MySQL query (Standard SQL) to get article information from drupal 7 (title, image, body, publish date). Only last revision.

Sounds like you want an EntityFieldQuery:
$query = new EntityFieldQuery;
$results = $query->entityCondition('entity_type', 'node')
->entityCondition('bundle', 'article')
->execute();
if (isset($results['node'])) {
$nodes = node_load_multiple(array_keys($results['node']));
foreach ($nodes as $node) {
$created = $node->created;
$image_uri = $node->field_image[$node->language][0]['uri'];
// ...
}
}

Ok, I found a solution:
SELECT node.title, body.body_value, FROM_UNIXTIME(node.created) AS Created, file_managed.uri AS image
FROM node INNER JOIN
field_data_body AS body ON node.nid = body.entity_id INNER JOIN
file_usage ON file_usage.id = node.nid INNER JOIN
file_managed ON file_usage.fid = file_managed.fid
WHERE (node.type = 'article')

Related

How to view data based on user in codeigniter

I want to view data from mysql in codeigniter based on user who is logged in
but I got an error "A Database Error Occurred". I think I wrote the wrong code
t.USER = $this->session->userdata('user_id');
Here's the code:
function get_rekomen()
{
$query = $this->db->query("SELECT
c.*,
t.produk_id,
t.id_transdet,
t.kategori_id,
t.total_qty,
t.USER
FROM
transaksi_detail AS t
LEFT JOIN
(
SELECT
g.id_produk,
p.slug_produk,
p.foto,
p.foto_type,
p.harga_diskon,
p.diskon,
p.harga_normal,
p.judul_produk,
g.kat_id,
k.judul_kategori
FROM
(
SELECT
MAX(m.id_produk) AS id_produk,
m.kat_id
FROM
produk AS m
GROUP BY
m.kat_id
)
AS g
INNER JOIN
produk AS p
ON p.id_produk = g.id_produk
LEFT JOIN
kategori AS k
ON k.id_kategori = g.kat_id
)
AS c
ON c.kat_id = t.kategori_id
WHERE
t.USER = $ this -> session -> userdata('user_id');
<<// i think here's the problem
ORDER BY
total_qty DESC limit 1")->result();
return $query;
}
and the question is what is the correct code?
Here's one solution, but first make sure on your controller the $this->load->library('session'); is loaded or you can just add in on autoload.php.
Also you must add parameter to your model that will handle the user_id in session, so for example here's your model looks like:
function get_rekomen($user_id) { ...your query here... }
Then on condition using the user_id will be
t.USER = $user_id;
So on your controller, you can call your model like:
$user_id = $this->session->userdata('user_id');
$this->ModelClass->get_rekomen($user_id);
Additional: On your login phase, if the user success from logging in, the you must set the user data on session such as this $this->session->set_userdata('user_data', $session_data);
Hope this helps!
Maybe you can use this. You need to define $user_id first before adding them to WHERE statement...
$user_id = $this->session->userdata('user_id');
$sql = "SELECT c.*, t.produk_id, t.id_transdet, t.kategori_id, t.total_qty, t.USER
FROM transaksi_detail AS t
LEFT JOIN(SELECT g.id_produk, p.slug_produk, p.foto, p.foto_type, p.harga_diskon, p.diskon, p.harga_normal, p.judul_produk, g.kat_id, k.judul_kategori
FROM(SELECT MAX(m.id_produk) AS id_produk, m.kat_id
FROM produk AS m
GROUP BY m.kat_id)
AS g
INNER JOIN produk AS p ON p.id_produk = g.id_produk
LEFT JOIN kategori AS k ON k.id_kategori = g.kat_id)
AS c ON c.kat_id = t.kategori_id
WHERE t.USER = '$user_id'
ORDER BY total_qty DESC limit 1";
$query = $this->db->query($sql);
return $query->result();
Hope this can help you...

MySQL - alternative for like - regexp?

i have got over one milion record in my database table.
When I use like is very slowly, when i use match against they lost some records.
I create help table:
tag_list
tag_id
tag_name
tag_rel_message
tag_id
messag_id
messages
message_id
message_text
in tag_list i add all words of $message_text - explode(" ", $message_text);
My new query is:
SELECT m.*
FROM tag_rel_messages trm
INNER JOIN messages m ON (trm.message_id = m.message_id)
INNER JOIN tag_list tl ON (trm.tag_id=tl.tag_id
WHERE tl.tag_name REGEXP 'pionas' AND tl.tag_name REGEXP 'website'
GROUP By trm.message_id
But not display any records.
What's wrong with this query?
Maybe i should use something other than REGEXP?
Thanks for help
I'm not sure how one column could match two things at the same time! You can use OR in place of AND, or you can use a single call to REGEXP.
SELECT m.*
FROM tag_rel_messages trm
INNER JOIN messages m ON (trm.message_id = m.message_id)
INNER JOIN tag_list tl ON (trm.tag_id=tl.tag_id
WHERE tl.tag_name REGEXP 'pionas|website'
GROUP By trm.message_id
You need to join with the tag_list and tag_rel_message tables twice to match two different tags.
SELECT m.*
FROM messages AS m
JOIN tag_rel_messages AS trm1 ON m.message_id = trm1.message_id
JOIN tag_list AS t1 ON t1.tag_id = trm1.tag_id
JOIN tag_rel_messages AS trm2 ON m.message_id = trm2.message_id
JOIN tag_list AS t2 on t2.tag_id = trm2.tag_id
WHERE t1.tag_name = 'pionas' AND t2.tag_name = 'website'
Another way to do it is to join with either tag, and count the number of results per message
SELECT m.*
FROM messages AS m
JOIN tag_rel_messages AS trm ON m.message_id = trm.message_id
JOIN tag_list AS t ON t1.tag_id = trm.tag_id
WHERE t.tag_name IN ('pionas', 'website')
GROUP BY m.message_id
HAVING COUNT(*) = 2
This second form is a little easier to generalize to any number of tags. Put all the tags in the IN clause, and change the HAVING clause to match the number of tags.
$words = array('pionas', 'website');
$tags_id = array();
foreach ($words as $key => $val) {
$sql = "SELECT tag_id FROM tag_list WHERE tag_name LIKE '%".$val."%'";
$records = $db->query($sql);
$tags_id[$key] = array_column($records, "tag_id");
}
$inner_array = array();
foreach ($tags_id as $k => $v) {
$short_name = "trm_".$k;
$inner_array[] = " INNER JOIN tag_rel_message as ".$short_name." ON ( ".$short_name.".message_id = m.message_id AND ".$short_name.".tag_id IN (".implode(", ", $v).")) ";
}
$sql = "SELECT DISTINCT m.* FROM messages m".implode(" ", $inner_array);
I think this is the same:
SELECT * FROM messages WHERE message_text like '%pionas%' AND message_text like '%website%'

Drupal 7 DB API Query with Condition db_or etc

I'm having a little issue with getting an sql query to work in drupal 7.
Basically, I'd like to know if my drupal code for the db_api is correct for the SQL query that I expect it to generate.
Please see code below:
/*
SQL Query
Note: The the 'a' in '%a%', is just a sample of some text input by a user.
*/
SELECT u.uid, fn.field_first_name_value, ln.field_last_name_value
FROM role r
JOIN users_roles ur ON (r.rid = ur.rid)
JOIN users u ON (u.uid = ur.uid)
JOIN field_data_field_first_name fn ON (fn.entity_id = u.uid)
JOIN field_data_field_last_name ln ON (ln.entity_id = u.uid)
WHERE (fn.field_first_name_value LIKE '%a%' OR ln.field_last_name_value LIKE '%a')
AND r.name = 'custom_role'
LIMIT 0, 5
/*
DRUPAL 7 DB API CODE
*/
$name = $_POST['name'];
$res = db_select('role', 'r');
$res->join('users_roles', 'ur', 'ur.rid = r.rid');
$res->join('users', 'u', 'u.uid = ur.uid');
$res->join('field_data_field_first_name', 'fn', 'fn.entity_id = u.uid');
$res->join('field_data_field_last_name', 'ln', 'ln.entity_id = u.uid');
$res->fields('u', array('uid'));
$res->fields('fn', array('field_first_name_value'));
$res->fields('ln', array('field_last_name_value'));
$or = db_or()->condition('fn.field_first_name_value', '%'.db_like($name).'%', 'LIKE');
$or->condition('ln.field_first_name_value', '%'.db_like($name).'%', 'LIKE');
$res->condition($or)->condition('r.name', 'custom_role', '=');
$res->range(0,5);
$res->execute();
Also, if there is way that I can see the generated sql by the db api, that would be great for debugging.
Thanks.
I cannot execute it because i do not have the same tables like you but your generated query looks good.
SELECT u.uid AS uid, fn.field_first_name_value AS field_first_name_value, ln.field_last_name_value AS field_last_name_value
FROM
{role} r
INNER JOIN {users_roles} ur ON ur.rid = r.rid
INNER JOIN {users} u ON u.uid = ur.uid
INNER JOIN {field_data_field_first_name} fn ON fn.entity_id = u.uid
INNER JOIN {field_data_field_last_name} ln ON ln.entity_id = u.uid
WHERE ( (fn.field_first_name_value LIKE :db_condition_placeholder_0 ESCAPE '\\') OR (ln.field_first_name_value LIKE :db_condition_placeholder_1 ESCAPE '\\') )AND (r.name = :db_condition_placeholder_2)
LIMIT 5 OFFSET 0
If you want to print the query yourself you can use
print $res->__toString() . "\n\n";
var_export($res->getArguments());
Or
watchdog('MY_QUERY_DEBUG', $res->__toString(), $res->getArguments());
To add it to your watchdog log.

SQL JOIN but include nulls

If I have 15 rows in one table and i join another table to it, can i still output all 15 even if i want to join where the value could be null? Basically can you JOIN + include nulls from the result of the join. For example:
1
2
3
4
5
6
After join only 3 have the join parameter
2
4
5
How can i display everything?
I tried the following:
"SELECT *
FROM `ultrait_wpl_properties`
JOIN ultrait_wpl_property_types
ON ultrait_wpl_properties.property_type = ultrait_wpl_property_types.id
ORDER BY ultrait_wpl_properties.id"
This part outputs duplicate IDs?
$sql = "SELECT *
FROM `ultrait_wpl_properties`
LEFT JOIN ultrait_wpl_property_types
ON ultrait_wpl_properties.property_type = ultrait_wpl_property_types.id
ORDER BY ultrait_wpl_properties.id ASC";
$result = mysqli_query($con, $sql); // Connect and run query
$dom = new DOMDocument(); // New DOM
$root = $dom->createElement('root'); // Create parent or root node
$dom->appendChild($root); // Append the root tag to the DOM
while($r = mysqli_fetch_assoc($result)){
$node = $textContent = null; // $node will equal $textContent which is null
$property = $dom->createElement('property'); // Create containing node
foreach($r as $column_name => $val) { // Loop through key value pairs
// so loop all the values on each row
Try these:
"SELECT *
FROM `ultrait_wpl_properties`
LEFT JOIN ultrait_wpl_property_types
ON ultrait_wpl_properties.property_type = ultrait_wpl_property_types.id
ORDER BY ultrait_wpl_properties.id"
OR:
"SELECT *
FROM `ultrait_wpl_properties`
RIGHT JOIN ultrait_wpl_property_types
ON ultrait_wpl_properties.property_type = ultrait_wpl_property_types.id
ORDER BY ultrait_wpl_properties.id"
shree.pat18 is correct it either depends on your situation to use INNER, RIGHT OR LEFT JOIN
Why do not you try left join
SELECT *
FROM `ultrait_wpl_properties`
LEFT JOIN ultrait_wpl_property_types
ON ultrait_wpl_properties.property_type = ultrait_wpl_property_types.id
ORDER BY ultrait_wpl_properties.id

How to write a complex sql query in zend2

I want to write a mySQL query like the following in zend framework 2.
How to convert it in zend Db select convention?
SELECT profiles.*,
user.email,
user.first_name,
user.last_name,
portfilio_images.profileImage,
images.url AS imgurl
FROM profiles
INNER JOIN user ON user.user_id = profiles.ownerId
LEFT JOIN (
SELECT *
FROM portfilio_images
WHERE portfilio_images.profileImage = '1'
) as portfilio_images ON portfilio_images.profileId = profiles.id
LEFT JOIN images ON images.id = portfilio_images.imageId
WHERE profiles.ownerId != '4' AND (profiles.name LIKE '%a%' OR user.first_name LIKE '%a%' OR user.last_name LIKE '%a%')
GROUP BY user.user_id
You can also use Zend\Db\Sql\Select that allows you to build complex queries programatically. See the documentation here:
http://zf2.readthedocs.org/en/release-2.1.1/modules/zend.db.sql.html#zend-db-sql-select
You could always just perform a raw query:
$sql = "SELECT * FROM test";
$statement = $abAdapter->query($sql);
$result = $statement->execute();
$resultSet = new ResultSet;
$resultSet->initialize($result);
return $resultSet;
Or if you want to add some parameters
$sql = "SELECT * FROM test where col = ?";
$statement = $dbAdapter->query($sql);
$result = $statement->execute(array(99));
$resultSet = new ResultSet;
$resultSet->initialize($result);
return $resultSet;