I'm stuck with creating a where query. I have table item with item_id, item_title, item_description, item_created, item_approved. I also have a table article with PK item_id (from item table) and article_body. The last table is media with medium_id, item_id (FK), medium_url and medium_type.
Now I would like to select all the data from media where item.item_approved is not NULL and where item.item_id ins't present in the article table.
Now I can select all the data from media where item.item_approved is not NULL. But now I need to do another check that he doesn't select the items that are also in article table. My query so far:
$repository = $entityManager->getRepository('VolleyScoutBundle:Media');
$query = $repository->createQueryBuilder('m')
->join('m.item', 'i')
->where('i.itemApproved is not NULL')
->getQuery();
Most likely that you must use 2 queries. With JOINs it can not be done.
Related
I want to perform the following raw SQL query in Laravel's Eloquent:
SELECT distinct user_id FROM order_payment WHERE user_id IN (SELECT user_id FROM order_payment where payment_status = 'paid' GROUP BY user_id HAVING COUNT(*) > 1);
here I am using where in with property user_id such that all rows in the same table(order_payment) having payment_status=paid and grouped by property user_id having count > 1 are selected and then finally we select distinct user_ids from the given set of user ids.
The overall objective of this query is to get all the rows where required column value(user_id's in this case) > 1...
Ex:
we have 3 rows > A, B, C
row A has user_id = 1;
row B has user_id = 1;
row C has user_id = 2;
result should have [user_id: 1] as the count becomes greater than 1
The above raw query work for me, but now that i am writing a api, I was wondering how this can be replicated in Eloquent.
PLEASE HELP!
So the eloquent way for this query could be done using the groupBy and havingRaw methods
we first select the columns which we need to aggregate
OrderPayment::select('user_id', \DB::raw('COUNT(user_id) as payment_made))
then we groupBy the arribute we need - groupBy('user_id'), Note that the property we group by has to be in the select statement or this wont work.
Now the final clause where we see if there are multiple row having the same user_id, we use > havingRaw('COUNT(user_id) > ?', [1])
Now the overall eloquent query looks like this
OrderPayment::select('user_id', \DB::raw('COUNT(user_id) as payment_made))
->groupBy('user_id')
->havingRaw('COUNT(user_id) > ?', [1])
->get();
Note that in the select clause we are passing the DB raw statement which passes as a string to the query builder and hence one should be careful with SQL injections.
I'm having difficulty trying to find the best way to get my results from a table. I want to get the targeted row from a table by one using the primary key from another using a foreign key.
The tables are would be set similar to this(minus a lot of other attributes for space):
user Table:
user_Id(pk)
name
type
venue_Id(unique/indexed)
venue Table:
venue_Id(fk)
rating
Logic flow is: user_Id is provided by a session variable. Query DB table 'user' to find that user. Go to type of user to identify if user is person or venue. Assuming user is venue, go to DB table 'venue' and query table for rating using foreign key from unique/indexed venue_Id from user table.
The query looks like
SELECT rating FROM `venue` WHERE `user_Id` = '$user_Id' AND `type` = 'venue'
Is this possible, and if so, what is the correct way to go about it?
You have a few ways to retrieve this information.
Using JOIN:
SELECT v.rating
FROM venue v INNER JOIN user u
ON v.venue_id= u.venue_id
AND u.`user_Id` = '$user_Id' AND u.`type` = 'venue'
Using an IN sub-query
SELECT rating
FROM venue
WHERE venue_id IN (SELECT venue_id FROM user
WHERE `user_Id` = '$user_Id' AND `type` = 'venue')
BTW, you should consider protect your code from potential SQL Injections
Its a bit unclear you explained that way.
From what I get, there is 2 table User and Venue.
In User table u have: user_id, venue_id, name, type.
While in Venue table u have: venue_id, rating.
You are expecting to get rating (Venue Table) while you use the WHERE clause in user_id and type which both stored on User Table.
Your Query:
SELECT rating FROM venue WHERE user_Id = '$user_Id' AND type = 'venue'
It is impossible to get it done like above because you are selecting from venue table while user_id and type is not from venue table. So it will make it unidentified even you have chaining the FK. Because FK will only to show and make some constraint to parent child table.
The query should be something like this:
SELECT rating FROM venue v JOIN user u on v.venue_id = u.venue_id WHERE u.user_Id = '$user_Id' AND u.type = 'venue'
Correct me if I am wrong..
Combining rows from two tables based on the tables having columns with equal values is called an equi-join operation, it's the pattern we typically use to "follow" foreign key relationships.
As an example:
$sql = "SELECT v.rating
FROM `venue` v
JOIN `user` s
ON s.venue_Id = v.venue_Id
AND s.type` = 'venue'
WHERE s.user_Id` = '" . mysqli_real_escape_string($con, $user_Id) ."'"
This isn't the only pattern, there are several other query forms that will return an equivalent result.
As an example of using an EXISTS predicate:
$sql = "SELECT v.rating
FROM `venue` v
WHERE EXISTS
( SELECT 1
FROM `user` s
WHERE s.venue_Id = v.venue_Id
AND s.type` = 'venue'
AND s.user_Id` = '"
. mysqli_real_escape_string($con, $user_Id)
."'"
)";
The original query appears to be vulnerable to SQL Injection; the example queries demonstrate the use of the mysqli_real_escape_string function to "escape" unsafe values and make them safe to include in SQL text. (That function would only be appropriate if you are using the mysqli interface. Using prepared statements with bind placeholders is another approach.
How do I select a column value as a column name and group the results as a row.
I have a table as such:
id articleId label value
1 1 title Example title
2 1 description This is the description
3 1 author Me
4 2 title Example of another type of article
5 2 description Short description
6 2 author Someone else
Is it possible to select all of the rows and use the label as the column name and the value as the value of that column name and then group them by the article name.
So how I would like to have it returned:
articleId title description author
1 Example title This is the.. Me
2 Example of an.. Short descr.. Someone else
I'm using this for a CMS where the user can define the fields for an article so we don't have to customize the table's. This is why i'm not making the tables as the I would like to have it returned. I am also aware that I can just as easily convert the result to this in php.
-- edit --
Can this be done without knowing what labels are added? In this example im using title, description and author. But it could very well be something totally different like title, shortDescription, availableTo, techInformation, etc.. The idea is that the article's are customizable for the user without needing to change the database and query's
I figured I'd better post as an answer, even if not what OP would like to hear. What you are asking to do is to populate a query with a variable number of columns based on the distinct values within column label, all associated with articleID. Taking your specific example, the following would be the resultant query that I would most likely go to in this instance (though the example from #Devart is equally valid)
SELECT
t.id,
t.articleId,
t1.value AS title,
t2.value AS description,
t3.value AS author
FROM `tableName` t
LEFT JOIN `tablename` t1
ON t1.article_id = t.article_id AND t1.label = 'title'
LEFT JOIN `tablename` t2
ON t2.article_id = t.article_id AND t2.label = 'description'
LEFT JOIN `tablename` t3
ON t3.article_id = t.article_id AND t3.label = 'author'
Now expanding this to account for up to n labels, we get the following query (metacode included, this query will NOT execute verbatim)
SELECT DISTINCT label FROM `tableName`;
SELECT
t.id,
t.articleId
// for (i=1;i<= number of distinct labels) {
,t[i].value AS [value[i]]
// }
FROM `tableName` t
// for (i=1;i<= number of distinct labels) {
LEFT JOIN `tablename` t[i]
ON t[i].article_id = t.article_id AND t[i].label = [value[i]]
// }
;
So what you can do is one of the following.
SELECT t.* FROM tablename t and then have PHP process it as required
SELECT DISTINCT label FROM tablename and have PHP build the second query with the many LEFT JOINs (or MAX / GROUP BY logic if preferred)
Create a Stored Procedure to do the same as #2. This would most likely be more efficient than #2 however may be less efficient overall than #1.
You can use pivote table trick -
SELECT
articleId,
MAX(IF(label = 'title', value, NULL)) AS title,
MAX(IF(label = 'description', value, NULL)) AS description,
MAX(IF(label = 'author', value, NULL)) AS author
FROM
table
GROUP BY
articleId
Try below :
select t1.articleId,t1.title,t1.description,t1.author
from tablename as t1
left join (select max(articleId) as articleId
from tablename
group by articleId ) as t2
on t1.articleId=tsm.articleId where [.....]
I have a mysql table called jos_users_quizzes with the following columns:
id
quiz_id
user_id
I have a second table called jos_users with this columns
id
name
username
department
the user_id on first table is linked with the id of second table so
quiz_id = id (jos_users)
How can build a query to multiple insert the ids of a selected department into the jos_users_quizzes table... in one click
I am thinking meabe a sub query or a loop, but no sure how.
Thanks in advance!
INSERT jos_users_quizzes (quiz_id, user_id)
SELECT $quizID, id
FROM jos_users
WHERE department = 'selected department'
With INSERT ... SELECT, you can quickly insert many rows into a table from one or many tables. For example
INSERT INTO jos_users_quizzes (quiz_id)
SELECT jos_users.id
FROM jos_users WHERE jos_users.department = 100;
What i want, to display rows from a table which is selected by a field from other table single value, lets say to display images from a table by last category id.
I have this type of query, but this return me all matching keys rows, if i inset LIMIT 1 then it return one row...
SELECT i.prof_image FROM profile_images i
JOIN images_cat cat ON (cat.cat_id = i.cat_id)
GROUP BY i.prof_image;
//OR LIMIT 1;
Any idea to fix this problem. (i.e. displaying the latest category images)?
This will work for your specific example.. If you need to be more selective, then please post some more details..
SELECT i.prof_image
FROM profile_images i
WHERE cat_id = (select max(cat_id) from images_cat)
SELECT * FROM table_1
LEFT JOIN table_2 ON table_1.id = table_2.id
This query will grab all things in table_2 that have the same id value.
Note that it is a LEFT JOIN - which means that if there are no matching values in table_2, it will still return the values from table_1.
What is your intent with using last()?
Hope this helps.