Multiple selects on one query - php

I would like to do a multiple select in mysql but have not had any joy. I have tried following examples on here and around the web but they do not seam to fit what I am trying to do.
My select statement is as follows
SELECT a.* FROM Calendar a
WHERE a.CalendarId = 256 AND a.Private = 0
UNION
SELECT b.* FROM Calendar b
WHERE b.CalendarId = 256 AND b.Private = 1 AND b.PrivateId = 11
To explain what I want above, I would like to return all Calendar rows that have a Private value of 0.
I would also like to filter this by selecting only those that have Private = 1 that have the PrivateId = 11 (in this example).
Thanks

Try :
SELECT *
FROM Calendar
WHERE CalendarId = 256
AND (Private = 0 OR (Private = 1 AND PrivateId = 11))

Related

How can I order the results of an SQL query by the count of another table based on a shard ID?

I have an SQL query that fetches posts from a database. Everything works fine, but now I need to order the results by the number of comments each post has. The comments are on a separate table and they have a post_id column that links it to the post. I need to order the posts by the count of the comments table based on a shard ID? I have tried everything but every time I try to add something to my query it stops running completely and leaves my page blank. I need help to know where to put the other JOIN statement. This is my query:
$union = "UNION ALL
(
SELECT DISTINCT wallposts.p_id,wallposts.is_profile_notes,wallposts.times_viewed,wallposts.columnTimesShared,
wallposts.marked,wallposts.secure_id,wallposts.reshared,wallposts.group_id,
wallposts.totaluploads,wallposts.WallUploadID,wallposts.type,
wallposts.value,wallposts.media,wallposts.youtube,wallposts.post_type,
wallposts.privacy,wallposts.tagedpersons,wallposts.with_friends_tagged,wallposts.emotion_head,wallposts.selected_emotion,wallposts.title,
wallposts.url,wallposts.description,wallposts.cur_image,
wallposts.uip,wallposts.likes,wallposts.userid,
wallposts.posted_by,wallposts.post as postdata,wallusers.*,
UNIX_TIMESTAMP() - wallposts.date_created AS TimeSpent,
PosterTable.mem_pic as posterPic, PosterTable.gender as posterGender,PosterTable.oauth_uid as poster_oauth_uid, PosterTable.username as posterUsername,
PosterTable.mem_fname as posterFname,PosterTable.work as posterWork,
PosterTable.mem_lname as posterLname,walllikes_track.id as PostLikeFound,wallposts.date_created
FROM
wallusers,wallusers as PosterTable, wallposts
LEFT JOIN walllikes_track
ON wallposts.p_id = walllikes_track.post_id AND walllikes_track.member_id = ".$user_id."
WHERE
wallusers.active = 1
AND
PosterTable.active = 1
AND
wallposts.group_id IN (".$groups.")
AND
wallposts.group_id != 0
AND
PosterTable.mem_id = wallposts.posted_by
AND
wallposts.marked < ".$this->flagNumber."
AND
wallusers.mem_id = wallposts.posted_by ) ";
The comments table is called wallcomments and it has a column called post_id. I know I need to use JOIN and COUNT but I don't know where to put it within my current code.
Try this query, I didn't run but i updated it.
SELECT wallposts.p_id,wallposts.is_profile_notes,wallposts.times_viewed,wallposts.columnTimesShared,
wallposts.marked,wallposts.secure_id,wallposts.reshared,wallposts.group_id,
wallposts.totaluploads,wallposts.WallUploadID,wallposts.type,
wallposts.value,wallposts.media,wallposts.youtube,wallposts.post_type,
wallposts.privacy,wallposts.tagedpersons,wallposts.with_friends_tagged,wallposts.emotion_head,wallposts.selected_emotion,wallposts.title,
wallposts.url,wallposts.description,wallposts.cur_image,
wallposts.uip,wallposts.likes,wallposts.userid,
wallposts.posted_by,wallposts.post as postdata,wallusers.*,
UNIX_TIMESTAMP() - wallposts.date_created AS TimeSpent,
PosterTable.mem_pic as posterPic, PosterTable.gender as posterGender,PosterTable.oauth_uid as poster_oauth_uid, PosterTable.username as posterUsername,
PosterTable.mem_fname as posterFname,PosterTable.work as posterWork,
PosterTable.mem_lname as posterLname,walllikes_track.id as PostLikeFound,wallposts.date_created
FROM
wallusers,wallusers as PosterTable, wallposts
WHERE
wallusers.active = 1
AND
PosterTable.active = 1
AND
wallposts.group_id IN (".$groups.")
AND
wallposts.group_id != 0
AND
PosterTable.mem_id = wallposts.posted_by
AND
wallposts.marked < ".$this->flagNumber."
AND
wallusers.mem_id = wallposts.posted_by ) " AND wallposts.p_id = walllikes_track.post_id AND walllikes_track.member_id = ".$user_id.";
A more readable query might look like this...
At least then we'd have a chance.
SELECT DISTINCT p.p_id
, p.is_profile_notes
, p.times_viewed
, p.columnTimesShared
, p.marked
, p.secure_id
, p.media...
FROM wallposts p...

Establish the order of some values

I have a series of queries that find out what is the best position every user had over a series of events (note: all users have the same $points_pos, so I am looking at a discriminating value). The query is looped for every user.
$max=$amount+1;
$i=1;
$highestsofar="99";
$numpointsall = "SELECT driver, position FROM standings_drivers WHERE season='42' AND points='$points_pos'";
$numall = mysql_query($numpointsall);
while ($i<$max) {
while ($row = mysql_fetch_row($numall)) {
$driver_id = $row[0];
$posvar = "SELECT position FROM results WHERE compId='$compId' AND driverId='$driver_id' AND eventID>='$firstevent' AND eventID<='$lastevent' AND (eventSession!='T' AND eventSession!='P' AND eventSession!='Q' AND eventSession!='Q1' AND eventSession!='Q2' AND eventSession!='QA') ORDER BY position ASC LIMIT 1";
$posres = mysql_query($posvar);
while ($row = mysql_fetch_row($posres)) {
$highestpos = $row[0];
}
$i++;
}
}
Having established the $highestpos for each of the $driver_id, how can I arrange them in order of best position (that is, the ones with the lowest $highestpos)?
Ideally, I want to achieve something that tells me:
$driver_id = 1
$driver_id = 2 etc
so that I can amend a table by putting them in the correct order of position.
EDIT: additional info
The results table look like this:
ID compId eventId eventSession driverId position
1 2 739 R 563 7
2 2 739 R 903 1
3 2 562 R 874 16
...
In the case above, assuming that 739 and 562 are the IDs of events in the range, I would like to order the three users in driverId as follows:
903 = 1st
563 = 2nd
874 = 3rd
Thank you for your help!
One thing about SQL is that it's typically much better than you (or I) are at getting data. The developers and architects for Microsoft, Oracle, etc. have spent a great deal of time and effort working on the best ways to select data, so trying to duplicate their efforts (like looping over results and getting values, etc.) is usually a mistake.
All of your code can likely be replaced with a single SQL query:
SELECT
SD.driver,
MIN(R.position) AS highest_position
FROM
Standings_Drivers SD
INNER JOIN Results R ON
R.driver = SD.driver AND
R.compId = ? AND
eventID >= ? AND
eventID <= ? AND
eventSession NOT IN ('T', 'P', 'Q', 'Q1', 'Q2', 'QA')
WHERE
SD.season = '42' AND -- Should this really be a string and not an integer?
SD.points = ?
GROUP BY
SD.driver
ORDER BY
MIN(R.position)
The question marks are where you would pass in your various parameters. Make sure that you're are executing this as a parameterized query and not just building up a complete string. I don't program in PHP, so I don't know the syntax for that. Googling for "sql injection php" should help you out there though.

Symfony2 bad response from query with maxresults and firstresult

I've meet a serious problem with setMaxResult and setFirstResult.
When i'm trying to get result without setMaxResults and setFirstResult, it works OK, all rows returned.
When i'm using offset = 0 and limit=10 , it works good, 10 rows returned.
When i'm using offset = 10 and limit = 10 , it return 5 rows (must be 7)
Another example, i've used offset = 0 , limit = 20 ,it returned 15 rows.But it must be 17 rows.
With offset=0 and limit = 30 , it returned all 17 rows .... Why this query works so bad ? With offset = 0 and limit 20, it should have returned all 17 rows... but not 15..
Code :
$eligibleCircles = $this->getAllCircles($user);
$results = $this->getEntityManager()
->createQuery(
'SELECT
e
FROM
TestBundle:Event e
LEFT JOIN
e.eligibleCircles eligibleCircles
WHERE
(
eligibleCircles in (:eligibleCircles)
OR
e.owner = :user
)
AND
e.eventStatus = :eventStatus
AND
NOT EXISTS (
SELECT
eh
FROM
TestBundle:EventHidden eh
WHERE
eh.user = :user
AND
eh.event = e
)
AND
e.startDate < :currentDate
ORDER BY e.startDate DESC
'
)
->setParameter('eventStatus', 3)
->setParameter('eligibleCircles', $eligibleCircles )
->setParameter('user', $user )
->setParameter('currentDate', new \DateTime('now') )
->setFirstResult($offset)
->setMaxResults($limitNr)
->getResult();
Cerad is correct with regard to the sql-limit not being useful when you have a join in your query.
If you want to paginate while using Doctrine2 there are some helpfull tools for you available.
Have a look at the documentation here:
http://doctrine-orm.readthedocs.org/en/latest/tutorials/pagination.html
You need a bit of extra code, but most of the complex stuff is handled for you.
It will also require 1 or 2 additional queries to find the correct records+data. This may or may not be a problem in your situation.

Write custom SQL Query in DataObject::get()

I am using Silverstripe version 2.4 . I did not update to new version because I have made many changes and now it is impossible for me to migrate to newer version.
I have a custom SQL query and I want the query to run in DataObject::get();
Here is my Query
SELECT STL.* FROM Page P join SiteTree_Live STL on P.ID = STL.ID join Site S on P.SiteID = S.ID where S.ID = 60 and STL.ShowInMenus = 1 and STL.ParentID = 0 and STL.CanViewType <> 'NotLoggedInUsers' ..
How can I write this query in DataObject::get();
Any help would be greatly appreciated.. Thanks
the easiest way is using the ORM to build that query, in 2.4 it could be done like this (only works if class Site has a has_many to Page, which I assume is the case here):
$site = DataObject::get('Site', 'ID = 60');
// the line below assumes that the has_many in site is called "Pages"
$pages = $site->Pages("ShowInMenus = 1 AND ParentID = 0 AND CanViewType <> 'NotLoggedInUsers'");
alternatively, if you want to save yourself that extra query for Site, you can do it with 1 DataObject::get() using the join parameter. should look something like this:
$pages = DataObject::get(
'Page',
"Site.ID = 60 AND ShowInMenus = 1 AND ParentID = 0 AND CanViewType <> 'NotLoggedInUsers'",
null,
'LEFT JOIN Site ON Site.ID = Page.SiteID'
);

How to union 2 SQL-query in Codeigniter? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
UNION query with codeigniter's active record pattern
I have the following code:
$language_id=$this->get_language_id($language_code);
$english_id=$this->get_language_id('en');
$query="SELECT e.label_value, t.user_id, t.votes, t.approved, t.language_value FROM labels e left outer join labels t on e.label_value=t.label_value WHERE e.language=$english_id and t.language=$language_id and (t.approved=1 or t.user_id=$user_id) and e.label_value in (select distinct label_value from labels WHERE language=$english_id order by label_value limit $start_index, 30) order by e.label_value, t.votes";
$query=$this->db->query($query);
$data=$query->result_array();
But I have got the following error:
This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
So, I need to do the folowoing part "select distinct label_value from labels WHERE language=$english_id order by label_value offset $start limit 30" in another query. Please, help me, how can I do it using CodeIgniter?
UPDATE:
There are is table labels
(label_value, language_value, language) - PK,
user_id,
timestamp,
approved,
votes
and I need to get all queries from this table (for example, it's name is t and e) with labels t.label_value, e.label_value (is exists), e.user_id, e.votes, e.timestamp where t.label_value=e.label_value(same label), t.language=45 (english language), e.language=24 (my language) and (e.user_id=121234 or e.approved=1). But I need all entries, and if (t.label_value!=e.label_value) I need to get this entry with NULL fields.
This is a limitation of MySQL and not PHP or CI. In order to get around it, you need to wrap your sub query in an aliased sub query so it becomes a derived table:
$language_id = $this->get_language_id($language_code);
$english_id = $this->get_language_id('en');
$query = "
SELECT e.label_value, t.user_id, t.votes, t.approved, t.language_value
FROM labels e
LEFT OUTER JOIN labels t on e.label_value=t.label_value
WHERE
e.language = $english_id
AND t.language = $language_id
AND (t.approved = 1 OR t.user_id = $user_id)
AND e.label_value IN (
SELECT label_value
FROM (
SELECT DISTINCT label_value
FROM labels
WHERE language = $english_id
ORDER BY label_value
LIMIT $start_index, 30
) i
)
ORDER BY e.label_value, t.votes
";
$query = $this->db->query($query);
$data = $query->result_array();
I think that will work, let me know if it doesn't and I will take another look at it.
EDIT
I'm having a little difficulty working out exactly what you are trying to do, but I think it might be something more like this:
SELECT t.label_value, t.user_id, t.votes, t.approved, t.language_value
FROM (
SELECT DISTINCT label_value
FROM labels
WHERE language = $english_id
) e
LEFT JOIN labels t ON e.label_value = t.label_value
WHERE
t.language = $language_id
AND (t.approved = 1 OR t.user_id = $user_id)
ORDER BY t.label_value, t.votes
LIMIT $start_index, 30
If this is still not correct, please show some example rows, and the result set you would like to retrieve from those rows.

Categories