I try to change database from 'MySQL' to 'PostgreSQL' but i have problem some of my query
SELECT
SUM( CASE WHEN b.DISPLAYNAME IS NULL THEN 0 ELSE 1 END ) AS NUMMENUDETAIL,
A.DISPLAYNAME AS GROUPNAME,
b.displayname,
D.NAME,
min( A.ROLEID ) AS ROLEID
FROM
usermenu A
LEFT JOIN usermenu B ON A.ID = B.GROUPID,
userrole C,
position D,
positiondetail E
WHERE
( A.GROUPID IS NULL )
AND D.id = E.position_id
AND A.ROLEID = E.userrole_id
AND A.ROLEID = C.ID
AND B.ROLEID = E.userrole_id
AND B.ROLEID = C.ID
AND b.displayname = 'Transaction Listing Report'
GROUP BY
A.DISPLAYNAME,
b.displayname
LIMIT 10
i use this query into "MySQL" it pass
but when i use in "PostgreSQL" it error, They want my to GROUP BY d.name
then if i GROUP BY it may have different result
How can i fix this ?
This query does not comply with the SQL standard, so it is unsurprising that it does not work on all databases. The standard requires that all columns in the SELECT list that do not appear only inside aggregate functions must be in the GROUP BY clause.
You can have the same effect by using the (again, non-standard) DISTINCT ON clause in PostgreSQL.
Is it possible to translate this SQL to DQL:
SELECT project.*, task.*
FROM `project`
LEFT JOIN (
SELECT * FROM task
WHERE (task.title LIKE '%add%' OR task.description LIKE '%add%' )
) task ON project.id = task.project_id
WHERE project.id = 50
I need Project to be returned even if there are no tasks found.
My initial DQL was:
SELECT p, t FROM MyBundle:Project p
LEFT JOIN p.tasks t
WHERE p.id = :id AND (t.title LIKE :title OR t.description LIKE :description)
ORDER BY t.id DESC
But this will return null if no task is found.
so i wanna try to get a filtering tag method, but in the database part is where i get lost, well kind of, because i wrote a raw query that works, but i need the Eloquent result so i can play with the relationships from the model class.
So here is the raw query:
$peticion = DB::select(DB::Raw("SELECT P.id, P.titulo, P.deadline, P.created_at, P.respuesta_id, U.usuario, C.titulo as categoria, C.clase_css as css, TG.Etiqueta
FROM peticiones P
JOIN usuarios U ON U.id = P.usuario_id
JOIN categorias C ON C.id = P.categoria_id
LEFT JOIN (
SELECT PT.peticion_id, T.nombre as Etiqueta
FROM tags T
JOIN peticion_tag PT ON PT.tag_id = T.id
) AS TG ON TG.peticion_id = P.id
JOIN (
SELECT PP.peticion_id
FROM (
SELECT PT.peticion_id, count(PT.peticion_id) AS conteo
FROM peticion_tag PT
WHERE PT.tag_id IN ( $etiquetas )
GROUP BY PT.peticion_id
) PP
WHERE PP.conteo = $len ) AS PPP
ON P.id = PPP.peticion_id
WHERE P.categoria_id = $id ;"));
what it does is that retrieve all the peticiones who has as many tags in it something like this in SO when filtering by tags.
But as i said i need the eloquent so this is my attempt to recreate the raw query:
$pet = Peticion::whereHas('tags', function($q) use ($tags, $len){
$q->whereIn('tag_id', $tags);
})
->where('categoria_id', '=', $id)
->get();
But it returns me all the peticiones who has this tag OR this tag, OR as many has the $tags array this get achieved with the raw query in the
WHERE PP.conteo = $len
but i dont know how to translate to eloquent.
Hope someone can help me, thanks a lot.
I currently have the following queries (and some surrounding vB code). I was hoping I could slim this up into a single SELECT statement versus having to run 10 more on each page to get that names of individuals.
$results = $db->query_read_slave("
SELECT user.id AS steam, user.skills AS level
FROM wcsp.wcgousers AS user
WHERE race = '_wcs_'
ORDER BY ABS(user.skills) DESC LIMIT 10
");
$rank = 1;
while ($user = $db->fetch_array($results)) {
$result = $db->query_first("
SELECT old.name AS name
FROM wcsp.warn_oldnames AS old
WHERE id = '$user[steam]'
ORDER BY lasttime
DESC LIMIT 1
");
$listing[] = array("id" => $user['steam'], "level" => $user['level'], "name" => $result['name'], "rank" => $rank);
$rank += 1;
}
I have tried LEFT JOIN but the issue I run into is that I would need a subquery in the LEFT JOIN similar to:
SELECT user.id AS steam, user.skills AS level, names.name AS name
FROM wcsp.wcgousers AS users
LEFT JOIN
(
SELECT names.name
FROM wcsp.warn_oldnames AS names
WHERE id = wcsp.wcgousers.id
ORDER BY lasttime DESC LIMIT 1
) AS names
ON names.id = users.id
WHERE users.race = '_wcs_'
Which won't work due to the different database check inside the subquery.
If I understand you correctly, you want to get the latest Name for every users.
SELECT a.id AS steam,
a.skills AS level,
b.name
FROM wcgousers a
INNER JOIN warn_oldnames b
ON a.ID = b.ID
INNER JOIN
(
SELECT ID, MAX(lasttime) max_date
FROM warn_oldnames
GROUP BY ID
) c ON b.ID = c.ID AND
b.lastTime = c.max_date
WHERE a.race = '_wcs_'
-- ORDER BY ABS(a.skills) DESC
-- LIMIT 10
I have this query
$query = "SELECT * FROM items WHERE itemStatus = '1' AND itemAdded > '$timestamp'";
Once this query has returned results I loop through the results
the results array is itemID, itemLocationID, categoryParentID, categoryID, itemName, itemDetails
During the loop I then run three other queries by calling functions within the same class
$locationName = $this->getLocationByName($locationID);
$categoryParentName = $this->getCategoryByName($categoryParentID);
$categoryName = $this->getCategoryByName($categoryID);
the function getLocationByName performs this query;
$q = mysql_query("SELECT * FROM locations WHERE locationID = '$locationID'");
this returns an array of locationID, locationName, locationLink
the function getCategoryByName performs this query;
$q = mysql_query("SELECT * FROM categories WHERE categoryID = '$categoryID'");
this returns an array of categoryID, categoryName, categoryLink
Could someone please help me optimize this query and maybe join them to save doing so many queries.
thanks in advance.
Im now using this query
$q = mysql_query("SELECT
i.itemID,
i.locationID,
i.categoryParentID,
i.categoryID,
i.itemName,
i.itemDetails,
l.*,
c.*
FROM
items i
inner join locations l on i.locationID = l.locationID
inner join categories c on i.categoryID = c.categoryID
WHERE
itemStatus = '1'
AND itemAdded > '$timestamp'")or die(mysql_error());
and the result is
Array
(
[itemID] => 81300
[locationID] => 17
[categoryParentID] => 21
[categoryID] => 183
[itemName] => blah
[itemDetails] => blah
[locationName] => brilliant it pulls in the location as expected.
[locationLink] => blah
[categoryName] => brilliant it pulls in the category as expected.
[categoryLink] => blah
)
[categoryName] => //these are missing for categoryParentID
[categoryLink] => //these are missing for categoryParentID
I would not use * in the select statement
The Query with the joins could be
SELECT
i.itemID,
i.itemLocationID,
i.categoryParentID,
i.categoryID,
i.itemName,
i.itemDetails,
l.*,
c.*
FROM
items i
inner join locations l on i.itemLocationID = l.locationID
inner join categories c on i.categoryID = c.categoryID
WHERE
itemStatus = '1'
AND itemAdded > '$timestamp'
I hope it be useful for you.
Cheers!
I think should be something similar to below query. I do not see where are you using $categoryParentName .
Using your queries and data:
SELECT * FROM items WHERE itemStatus = '1' AND itemAdded > '$timestamp'
SELECT * FROM locations WHERE locationID = '$locationID'
SELECT * FROM categories WHERE categoryID = '$categoryID'
$locationName = $this->getLocationByName($locationID);
$categoryParentName = $this->getCategoryByName($categoryParentID);
$categoryName = $this->getCategoryByName($categoryID);
Please let me know if this returns expected result set. Hope this helps
SELECT
it.itemID, it.itemLocationID, it.categoryParentID, it.categoryID, it.itemName, it.itemDetails,
l.locationID, l.locationName, l.locationLink,
c.categoryID, c.categoryName, c.categoryLink
FROM items it
LEFT JOIN locations l ON l.locationID = it.itemLocationID
LEFT JOIN categories c ON c.categoryID = it.categoryID
WHERE
it.itemStatus = '1'
AND it.itemAdded > '$timestamp'
Update query using categoryParentID - i am not saying is efficient but you can test and optimize as needed.
One option is to update above query - not sure that will work - and for large result sets using OR is not efficient:
LEFT JOIN categories c ON (c.categoryID = it.categoryID OR c.categoryID = it.categoryParentID)
The other option that i see is to get 2 result sets (see below) - one for categId = categId and second for categId = categParentId and combine the result set in one big result set.
SELECT
t.itemID, t.itemLocationID, t.categoryParentID, t.categoryID, t.itemName, t.itemDetails,
l.locationID, l.locationName, l.locationLink,
t.categoryID, t.categoryName, t.categoryLink
FROM
(
SELECT
it.itemID, it.itemLocationID, it.categoryParentID, it.categoryID, it.itemName, it.itemDetails,
c.categoryID, c.categoryName, c.categoryLink
FROM items it
INNER JOIN categories c ON c.categoryID = it.categoryID
WHERE
it.itemStatus = '1'
AND it.itemAdded > '$timestamp'
UNION -- [ALL]
SELECT
it.itemID, it.itemLocationID, it.categoryParentID, it.categoryID, it.itemName, it.itemDetails,
c.categoryID, c.categoryName, c.categoryLink
FROM items it
INNER JOIN categories c ON c.categoryID = it.categoryParentID
WHERE
it.itemStatus = '1' AND
it.itemAdded > '$timestamp'
) AS t
LEFT JOIN locations l ON l.locationID = t.itemLocationID
Other idea - not tested and assuming that id are int - will have to cast as string / char. There are a few options how you can write this query - if you post a structure table and some dummy data i am sure that someone will create a demo / sqlfiddle.
SELECT
it.itemID, it.itemLocationID, it.categoryParentID, it.categoryID, it.itemName, it.itemDetails,
l.locationID, l.locationName, l.locationLink,
c.categoryID, c.categoryName, c.categoryLink
FROM items it
LEFT JOIN locations l ON l.locationID = it.itemLocationID
WHERE
it.itemStatus = '1'
AND it.itemAdded > '$timestamp'
AND c.category ID IN ( SELECT GROUP_CONCAT(categs) FROM (SELECT CONCAT(categoryID, ",", categoryParentID) AS categs FROM items ))
Unless I'm missing something obvious, I'd probably suggest something like this as a first start:
select *
from items i
join locations l
on i.location_id=l.location_id
join categories c
on i.category_id=c.category_id
where item_status='1'
and itemAdded > '$timestamp'