django using .extra() got error `only a single result allowed for a SELECT that is part of an expression` - sql

I'm trying to use .extra() where the query return more than 1 result, like :
'SELECT "books_books"."*" FROM "books_books" WHERE "books_books"."owner_id" = %s' % request.user.id
I got an error : only a single result allowed for a SELECT that is part of an expression
Try it on dev-server using sqlite3. Anybody knows how to fix this? Or my query is wrong?
EDIT:
I'm using django-simple-ratings, my model like this :
class Thread(models.Model):
#
#
ratings = Ratings()
I want to display each Thread's ratings and whether a user already rated it or not. For 2 items, it will hit 6 times, 1 for the actual Thread and 2 for accessing the ratings. The query:
threads = Thread.ratings.order_by_rating().filter(section = section)\
.select_related('creator')\
.prefetch_related('replies')
threads = threads.extra(select = dict(myratings = "SELECT SUM('section_threadrating'.'score') AS 'agg' FROM 'section_threadrating' WHERE 'section_threadrating'.'content_object_id' = 'section_thread'.'id' ",)
Then i can print each Thread's ratings without hitting the db more. For the 2nd query, i add :
#continue from extra
blahblah.extra(select = dict(myratings = '#####code above####',
voter_id = "SELECT 'section_threadrating'.'user_id' FROM 'section_threadrating' WHERE ('section_threadrating'.'content_object_id' = 'section_thread'.'id' AND 'section_threadrating'.'user_id' = '3') "))
Hard-coded the user_id. Then when i use it on template like this :
{% ifequal threads.voter_id user.id %}
#the rest of the code
I got an error : only a single result allowed for a SELECT that is part of an expression
Let me know if it's not clear enough.

The problem is in the query. Generally, when you are writing subqueries, they must return only 1 result. So a subquery like the one voter_id:
select ..., (select sectio_threadrating.user_id from ...) as voter_id from ....
is invalid, because it can return more than one result. If you are sure it will always return one result, you can use the max() or min() aggregation function:
blahblah.extra(select = dict(myratings = '#####code above####',
voter_id = "SELECT max('section_threadrating'.'user_id') FROM 'section_threadrating' WHERE ('section_threadrating'.'content_object_id' = 'section_thread'.'id' AND 'section_threadrating'.'user_id' = '3') "))
This will make the subquery always return 1 result.
Removing that hard-code, what user_id are you expecting to retrieve here? Maybe you just can't reduce to 1 user using only SQL.

Related

cfsavecontent display double apostrophe in SQL statement

I have several OR in my SQL statement so I want to save a chuck of it in a cfsavecontent. Here is that part:
<cfsavecontent variable="checkDepartment">
<cfif #wrkDept# EQ #dept[2][1]#>
Department = 'Health' AND
<cfelse>
Department = '#wrkDept#' AND
</cfif>
</cfsavecontent>
But the error I get on the page shows 2 sets of apostrophes around the word Health.
SQL
SELECT COUNT(*) AS numItems
FROM IT_PROJECTS
WHERE
Department = ''Health'' AND
status = 'Cancelled'
Can anyone help me to only get a single apostrophe? Thanks
So this answer seems a lot more complicated than it really is. And without knowing specifically what your query looks like (re:OR conditions), I'm not really sure how to structure it. It can be better. The goal should be to make one single trip to your SQL server with the query that makes the most sense for the data you're trying to get. I'm not sure what you are trying to do with cfsavecontent, but I don't think you need it.
The bulk of my example query (https://trycf.com/gist/4e1f46bfa84a6748aced0f9ee8221c6d/acf2016?theme=monokai) is setup. I chose to go with a cfscript format, because as Redtopia said, I also find it much easier to build a dynamic query in cfscript.
After initial setup, I basically just script out the variables I'll use in my final queryExecute().
// Base query.
qry = "SELECT count(*) AS theCount FROM IT_PROJECTS WHERE 1=1 " ;
// This is our dynamic filter that we build below.
qfilter = {} ;
// Query options.
opts = { "dbtype":"query" } ;
After we have our base, I build up the dynamic part of the query. This is the part that will likely change quite a bit depending on your current needs and setup.
For the first part, I basically replaced your cfif with a ternary evaluation. I'm not sure how your data plays into the evaluation of dept or where that array comes from. But from there I build a basic included statement of the query and set up the queryparam values for it. Then I add a second check that will pick a different set of values for the query (currently based on even/odd seconds). Again, I'm not sure of the intent of your query here, so I just made something dynamic.
//////////// BUILD DYNAMIC FILTER ////////////
qdept = ( wrkDept == dept[2][1] ) ? 'Health' : wrkDept ;
/// This one is an included filter:
qry &= " AND department = :dpt AND status = :sts " ;
qfilter.dpt = {"value":qdept,"cfsqltype":"CFSQLVARCHAR"} ;
qfilter.sts = {"value":"Cancelled","cfsqltype":"CFSQLVARCHAR"} ;
/// Adding Dynamic ORs
// Dynamically set status based on even/odd seconds.
qStatus = ( now().second()%2==0) ? "Cancelled" : "Active" ;
qry &= " OR ( department = :dpt2 AND status = :sts2 ) " ;
qfilter.dpt2 = {value:"IT",cfsqltype:"CFSQLVARCHAR"} ;
qfilter.sts2 = {value:qStatus,cfsqltype:"CFSQLVARCHAR"} ;
This gives us a SQL string that looks like:
SELECT count(*) AS theCount
FROM IT_PROJECTS
WHERE 1=1
AND department = :dpt AND status = :sts
OR
( department = :dpt2 AND status = :sts2 )
With a SQL statement, the placement of AND and OR conditions can greatly impact the results. Use parenthesis to group conditions how you need them.
After we've built the query string, we just have to plug it and our queryparams into the queryExecute().
result = queryExecute( qry , qfilter , opts ) ;
And if we want to output our data, we can go:
writeOutput("There are " & result.theCount & " records." ) ;
Which gives us:
There are 8 records.
Again, I don't know what your main conditions look like. If you can give me an example of a query with a bunch of ORs and ANDs, I'll try to modify this for you.

count sql query used in rails 4

How to use count query in rails 4. I try to use , but I get
undefined method `where' for 57:Fixnum
my sample code is,
#empcount = Employee.count("emp_name")
.where("org_id = ? ", current_user.org_id)
What is the error with that?
Employee.count("emp_name") would return the total count of the employees.emp_name. A logical re-ordering of your query should return the result you're looking for:
#empcount = Employee.where("org_id = ? ", current_user.org_id).count("emp_name")
You are applying .where on integer value returned by count
Change your query to:
#empcount = Employee.where(org_id: current_user.org_id).count
Is this of any use?
#empcount = Employee.where(org_id: current_user.org_id).count
You need to find all employees by org_id and then do a count on all rows returned, right?

Hibernate createSQLQuery and Toad SQL query return different results - parameter problems?

I'm a newbie at Hibernate so excuse me if some of this is glaringly obvious but it's been a very, very long day. I am trying to create and execute a simple query in Hibernate and Toad/Oracle.
The Toad/Oracle sql reads:
select
count(*)
from
fpps_owner.fee_claim_payment_lines l,
fpps_owner.fee_claim_payments p
where
l.fee_claim_payment_id = p.fee_claim_payment_id and
p.claim_index = 87167895
The above returns 10 records, which is correct
The following Java code returns 0 records, which is NOT correct
String sLinesAvailable =
"select count(*) from " +
"fpps_owner.fee_claim_payment_lines l, fpps_owner.fee_claim_payments p " +
"where " +
"l.fee_claim_payment_id = p.fee_claim_payment_id and p.claim_index = :id";
Query qLinesAvailable = em.createNativeQuery(sLinesAvailable);
qLinesAvailable.setParameter("id", "87167895"); // fails
qLinesAvailable.setParameter("id", 87167895); // fails
List<Object> out = (List<Object>) qLinesAvailable.getResultList();
BigDecimal x = (BigDecimal) out.get(0);
Returns 0 records. Using .getSingleResult() also returns 0 records.
What am I missing here?
Any help would be GREATLY appreciated!
If you are not seeing any malformed query errors, it seems like the parameter is not binding correctly.
To debug, I'd print out that SQL statement the line after you set the parameter. This is the only way you can see the SQL after the parameter is set in order to compare it with Toad.
What does your binding file look like? Maybe you have a different name in there for the ID, so it's not able to find it based on the name. Trying binding with the parameter's order value, just as a test.
This might give some ideas: http://www.mkyong.com/hibernate/hibernate-parameter-binding-examples/
Best of luck! We've all been there :)
What happens when you try:
(Number) query.getSingleResult();
Your query isn't returning a list, but rather just a count.
Good luck.

My simple sql update query is not working right :(

I've got a simple sql query that is trying to update a single row. The code came from some Linq-to-sql code (i used Profiler to grab it), but please don't worry about the source (L2S) ... that's irrelivant to the question.
Now, when i try and do an update with the where clause, I get 0 rows updated.
I then try and do a select with the same where clause. i get a single result back. Ok, so the data is there.
It's only when i turn off some of the where clause statements does the query finally work. I just don't get it :(
I can't really explain it. So I made a video showing this.
Please watch the video on YouTube here.
Can anyone help? It's really weird :(
Database is MS-SQL 2008.
-- UPDATE
The sql i'm trying to execute (after i've cleaned it up from L2S)..
update tblBoardPost
set IsSticky = 1
where IdBoardPost = 1278
and IdAddress = 212787
and Subject = N'ttreterte'
and Banner is null
and UniqueSubject = N'ttreterte5'
AND (NOT ([IsAnnouncement] = 1))
AND (NOT ([IsSticky] = 1))
AND (NOT ([IsLocked] = 1))
and IsVisible = 1
and IdUserModified = 1
AND [IdNewsArticle] IS NULL
AND [IdList] IS NULL
(note: yes, i know the NOT (blah = 1)) is weird, but that's L2S that made that.
Update 2:
The code in the video is being ran in a transaction/rollback trans. this means that if i do run one of those weird scenario's that works, the change works .. but the rollback undoes it .. so when i run it a 2nd time .. the original value has been returned to the db row.
Also, in the vid, the select query is not exactly the same as the update query .. because i've been trying so many permutations (with no luck) .. so by the time i made the vid .. i forgot to show the original code. That said, the same code in both the select statement and the update/where statement (when i copy/paste on my machine) reproduces the exact same probs :(
Update 2 :)
As per Lieven's request, here's the screenshot showing the code and then the results.
alt text http://img196.imageshack.us/img196/7111/lieven.png
I checked your video, and you should try the same SQL conditions, that you used to return one row in your select query, in your update query. The conditions in the two SQL statements in your video aren't the same, and I don't really care why; they're not apples to apples.
Just copy and paste the working WHERE clause over the non-working one.
In the video, your select goes like
and not IsAnnouncement = 1
wich gives entirely different results as in your update
and not (IsAnnouncement = 1)
It seems you are suffering from an operator precedence issue .
Edit
as the queries don't match in your video and although you say they have matched could you copy paste following script and let us know if or if they do not give you the same results? (I for one would have a hard time believing that the rows affected would differ)
begin tran
select *
from tblBoardPost
where
IdBoardPost = 1278
and IdAddress = 212787
and Subject = N'ttreterte'
and Banner is null
and UniqueSubject = N'ttreterte5'
AND (NOT ([IsAnnouncement] = 1))
AND (NOT ([IsSticky] = 1))
AND (NOT ([IsLocked] = 1))
and IsVisible = 1
and IdUserModified = 1
AND [IdNewsArticle] IS NULL
AND [IdList] IS NULL
update tblBoardPost
set IsSticky = 1
where
IdBoardPost = 1278
and IdAddress = 212787
and Subject = N'ttreterte'
and Banner is null
and UniqueSubject = N'ttreterte5'
AND (NOT ([IsAnnouncement] = 1))
AND (NOT ([IsSticky] = 1))
AND (NOT ([IsLocked] = 1))
and IsVisible = 1
and IdUserModified = 1
AND [IdNewsArticle] IS NULL
AND [IdList] IS NULL
rollback tran

SELECT MAX query returns only 1 variable + codeigniter

I use codeigniter and have an issue about SELECT MAX ... I couldnot find any solution at google search...
it looks like it returns only id :/ it's giving error for other columns of table :/
Appreciate helps, thanks!
Model:
function get_default()
{
$this->db->select_max('id');
$query = $this->db->getwhere('gallery', array('cat' => "1"));
if($query->num_rows() > 0) {
return $query->row_array(); //return the row as an associative array
}
}
Controller:
$default_img = $this->blabla_model->get_default();
$data['default_id'] = $default_img['id']; // it returns this
$data['default_name'] = $default_img['gname']; // it gives error for gname although it is at table
To achieve your goal, your desire SQL can look something like:
SELECT *
FROM gallery
WHERE cat = '1'
ORDER BY id
LIMIT 1
And to utilise CodeIgniter database class:
$this->db->select('*');
$this->db->where('cat', '1');
$this->db->order_by('id', 'DESC');
$this->db->limit(1);
$query = $this->db->get('gallery');
That is correct: select_max returns only the value, and no other column. From the specs:
$this->db->select_max('age');
$query = $this->db->get('members');
// Produces: SELECT MAX(age) as age FROM members
You may want to read the value first, and run another query.
For an id, you can also use $id = $this->db->insert_id();
See also: http://www.hostfree.com/user_guide/database/active_record.html#select
CodeIgniter will select * if nothing else is selected. By setting select_max() you are populating the select property and therefore saying you ONLY want that value.
To solve this, just combine select_max() and select():
$this->db->select('somefield, another_field');
$this->db->select_max('age');
or even:
$this->db->select('sometable.*', FALSE);
$this->db->select_max('age');
Should do the trick.
It should be noted that you may of course also utilize your own "custom" sql statements in CodeIgniter, you're not limited to the active record sql functions you've outlined thus far. Another active record function that CodeIgniter provides is $this->db->query(); Which allows you to submit your own SQL queries (including variables) like so:
function foo_bar()
{
$cat = 1;
$limit = 1;
$sql = "
SELECT *
FROM gallery
WHERE cat = $cat
ORDER BY id
LIMIT $limit
";
$data['query'] = $this->db->query($sql);
return $data['query'];
}
Recently I have been utilizing this quite a bit as I've been doing some queries that are difficult (if not annoying or impossible) to pull off with CI's explicit active record functions.
I realize you may know this already, just thought it would help to include for posterity.
2 helpful links are:
http://codeigniter.com/user_guide/database/results.html
http://codeigniter.com/user_guide/database/examples.html