cakephp2 return one random record from database - mysql

I am experiencing a problem with my find to return a random record.
The thing is, the condition is not working for some reason.
DB:
quotes:
title (varchar255)
content (varchar255)
published (tinyint(1) NULL default = 0)
$random_quotes = $this->Quote->find('all',array('condition'=>array('Quote.published'=>1),'order'=>array('rand()'),'limit'=>1));
It returns 1 quote no mather what published = 0/1. It does not use the condition at all in the find. Have tried a find first as well. still.. published 0/1 does not mather. It returns a record no mather what.
Anyone know why this is happening??
I only have 2 quotes in the db now, and both = published = 0, still the find returns a result.
Thanks for any help on this!!!
-Tom

The condition option should be conditions (plural), otherwise it queries with no conditions.

Related

sqlalchemy.orm.subquery does not seem to load only specific columns

how can i load only specific columns when using subquery?
It seems like subquery loads all the columns from the table even though I included load_only option before calling subquery.
Code snippet is
results = session.query(User).options(load_only(User.name, User.fullname))
results = results.subquery()
The first result statement only loads name and fullname from User but the second result statement loads all the columns.
Any help is greatly appreciated. Thanks so much.
I just found a solution. It works if i do
results = session.query(User.name, User.fullname)
results = results.subquery()
Not sure if anynone has a better solution?

Lowest low since barssince - Pine Script v4

looking for a help on this issue...I want to get the lowest low since certain condition happened.
With barssince I get the number of bars since the condition happened (I plotted it and it's correct) but when I pass the variable into lowest function, it returns study error.
Here is a code which I hoped would return the lowest value since condition happened but it's not happening.
value_since_last_close = valuewhen((tradeline > tradeline[1]) or (tradeline < tradeline[1]), close, 0)
bars_since = barssince(value_since_last_close)
lowest_low = lowest(low, bars_since)
Many thanks in advance!

How to update the balance with random value (mysql) when a user registers the website?

For one of my courses, I'm trying to create banking system website using mysqldb and to write the code that make it possible for me to update users balance with random value while registration so the balance will not depend on the user's registration inserted information. i want the value to be inserted to the right spot in the table, only if this spot is null.
i used the code below:
$cursor = $MySQLdb->prepare("UPDATE users SET Balance=(Select FLOOR(0+ RAND() * 10000)) WHERE Balance=null AND userID=<userID>;")
I hope I was understood.
Thanks in advance
First of all, I would never put a calculation in a query string ;)
Also don't overcomplicate the rand() function. Take a look on the docs: rand() function docs
And lastly maybe think about it that is it a good idea to leave it on null? Maybe you could do something like 1 or so. (Only if it not possible for someone to have 1 money!!)
Do something like:
$balance_variable = $balance_variable = rand(5000, 10000);
$userID_variable = /*specify it somehow*/;
$cursor = $MySQLdb->prepare("UPDATE users SET Balance=? WHERE Balance IS NULL AND userID=?");
$cursor->bind_param('ss', $balance_variable, $userID_variable);
$cursor->execute();

MYSQL Selecting specific rows or first row if doesn't exist

I have a table of texts from various dates. Each is indexed by service, variation, and page and sub-page ids.
I need to fetch all entries for a given service, page and sub-page. i.e. each variation! BUT If the particular specific subpage doesn't exist, I need it to fetch the first subpage for that page, rather than nothing for that variation.
This is my code -
SELECT * FROM frames f
LEFT JOIN varients v ON f.varient_id = v.varient_id AND f.service_id = v.service_id
ẀHERE f.service_id = :sid
AND f.frame_id = :fid
AND (f.subframe_id = :subid
OR f.subframe_id = (
select min(subframe_id) from frames ff
ẀHERE ff.service_id = f.service_id
AND ff.varient_id = f.varient_id AND ff.frame_id = f.frame_id
)
)
GROUP BY f.service_id, f.varient_id, f.frame_id
ORDER BY f.service_id, v.varient_date, f.frame_id, f.subframe_id
but as often as not this just gives the minimum rather than the specific, even when the specific value exists. I'm pretty sure that the OR isn't what I need..
I've tried working with UNION as per some other answers, but since I want more than a single result, I can't seem to work it out!
Thanks for any help ..
OK. I managed to achieve what I wanted. Two days of messing with this, and finally work it out after posting a question. I was helped by one of the 'related' questions, which whilst not giving me an answer, made me think about it a different way -
I basically turned the whole thing inside out: As i only wanted one result per variation, I used that as the primary table. Then Joined the 'frames' table twice, once for the specific value, and once for the first value (found using a search for MIN().) Used IFNULL to return the second record if the first wasn;t found. An extra IS NOT NULL check against the second record within the WHERE to avoid returning anything where there is nothing stored against the variation record.
SELECT v.service_id, v.varient_id, IFNULL(f.frame_id,ff.frame_id)as frame_id,
IFNULL(f.subframe_id,ff.subframe_id) as subframe_id , IFNULL(f.frameunique, ff.frameunique) as frameunique, IFNULL(f.frame_content,ff.frame_content) as framecontent
FROM varients v
LEFT JOIN `frames` f ON `f`.`varient_id` = `v`.`varient_id` AND `f`.`service_id` = `v`.`service_id` AND `f`.`frame_id` = 698 AND `f`.`subframe_id` = 0004
LEFT JOIN `frames` ff ON `ff`.`varient_id` = `v`.`varient_id` AND `ff`.`service_id` = `v`.`service_id` AND `ff`.`frame_id` = 698
AND `ff`.`subframe_id` = (select min(`subframe_id`) from `frames` `fff` where `fff`.`service_id` = `v`.`service_id`
AND `fff`.`varient_id` = `v`.`varient_id` AND `fff`.`frame_id` = 698 )
where `v`.`service_id` = 3 AND ff.frameunique IS NOT NULL
ORDER BY `f`.`service_id`, `v`.`varient_date`, `f`.`frame_id`, `f`.`subframe_id`
Posting this in case it helps anybody else. It still needs tidying but it works. Thanks for the comments. :)

Return single value based on conditional CASE

I have no background with MySQL and have not been able to find the appropriate stepping stones to accomplish writing this particular query.
Objective:
I have created a report that shows the approval status of artwork per page. Artists have to access the proof however to determine if there is any markup/notes on each page. I want to add single column to the report that will have one of three string values per page for each proof. The string will either be "Yes", No", or "Missed" based on certain conditions.
Each proof can have multiple pages. Each page can have multiple marks (think of drawing a circle around something). Each mark can have multiple notes. This is where, for me, things get hazy. I am aware of the need to avoid RBAR queries, but I am unsure how to query against multiple comments and then marks by page.
Conditions:
This is the RBAR query I have for handling the notes/comments. This is fine for dealing with each comment, but obviously on a report there is no reason to see each comment row.
SELECT *,
CASE WHEN note IS NULL OR ' ' AND deleted = FALSE
THEN 'Missed' ELSE 'Yes'
END AS 'Comment'
FROM rvm_comment
Knowing that a mark can have multiple comments, I need to determine if any rows in rvm_comment.note are NOT NULL or contain just a space, ' '. If so, the mark is represented as "Yes". Otherwise the mark would be "Missed".
This should then be condensed/nested in a manner that each mark is compared.
If any mark on a page is "Yes" then output in that row would be "Yes". Otherwise, "Missed".
If this doesn't make sense, hopefully the following information will shed some light.
Tables and Relationships:
DSE_OBJECT Table:
This table is associated with a request that a proof can be attached to. The ID is the PK.
RVM_REVIEW_OBJECT Table:
This table is essentially the proof instance itself. A proof can have any number of pages (min 1). ID is the PK, review_object is the FK.
RVM_MARK Table:
This table contains information on marks that are added to a proof, including the page they exist on. ID is the PK, review_object is the FK. (NOT LISTED) Deleted is used to prevent returning results where a mark is deleted by the user. rvm_mark.deleted = FALSE
RVM_COMMENT Table:
This table is where the notes (strings) are stored. Deleted is used to prevent returning results where a note is deleted by the user (rvm_comment.deleted = FALSE). There is a flaw in the system where a comment can be created but if the user doesn't hit "enter" on their keyboard after typing the text is not saved in to the DB. This is why we need to test for NULL in rvm_comment.note.
Raw Data for Testing and Summary: Dropbox with CSVs for the tables
As a courtesy I have included some raw data in CSV form for anyone will to try it out. (click Dropbox link above).
So, to summarize again. I am trying to write a query that will condense those tables to a single string (AS Comment),for each rvm_mark.page_no. The string is based on a) whether or not rvm_comment.note is NULL or ' ', and b) whether any rvm_mark.id that has matching rvm_mark.page_no, has rvm_comment.note that isn't NULL.
EDIT UPDATE 12/14/16:
Thanks to Barmar I was able to take a step towards the final result. I am currently stuck on trying to return the string 'No' for any situations where there are no comments. This should only be when rvm_review_object.id does not have a matching value in rvm_mark.review_object.
SELECT rvm_review_object.dse_object_id, rvm_review_object.id,
T_Mark.creator, T_Mark.review_object,
CASE WHEN T_Mark.review_object IS NULL THEN 'No'
ELSE T_Mark.Comment
END AS Comment
FROM rvm_review_object
LEFT JOIN(
SELECT rvm_mark.review_object, rvm_mark.creator, rvm_mark.id,
CASE WHEN MAX(T_Comment.Comment = 'Yes') = 1 THEN 'Yes'
ELSE 'Missed'
END AS Comment
FROM rvm_mark
LEFT JOIN(
SELECT rvm_comment.mark,
CASE WHEN MAX((rvm_comment.note IS NULL OR rvm_comment.note = '')
AND rvm_comment.deleted = FALSE) = 1
THEN 'Missed'
ELSE 'Yes'
END AS Comment
FROM rvm_comment
GROUP BY rvm_comment.mark) AS T_Comment
ON T_Comment.mark = rvm_mark.id
WHERE rvm_mark.deleted = FALSE
GROUP BY rvm_mark.review_object) AS T_Mark
ON T_Mark.review_object = rvm_review_object.id
WHERE rvm_review_object.creator != T_Mark.creator
You need to group the query by mark. You can then use MAX() to determine if any of the rows in the group match the condition.
SELECT mark,
CASE WHEN MAX((note IS NULL OR note = '') AND deleted = FALSE) = 1
THEN 'Missed'
ELSE 'Yes'
END AS Comment
FROM rvm_comment
GROUP BY mark