Query does not show expected result - sql

I'll try to be as specific as i can here, so here's the query using MsAccess.
SELECT MsThread.ID,
MsThread.ThreadName,
COUNT(MsThread.ThreadName) AS TotalPost
FROM MsThread
LEFT OUTER JOIN MsPosts
ON MsThread.ThreadName = MsPosts.ThreadName
GROUP BY MsThread.ID, MsThread.ThreadName, MsThread.ThreadCategory
When I ran the query in MsAccess it returns this:
It shows that I have 4 rows ( # of threads ), and the number 5,2,1,1 is the number of posts with specified threads. Here I've been trying to get the resultset to return 4 instead of 9 so I can loop it without no invalid cursor state error.
rs.last();
int row = rs.getRow();
that returns 8, so i am guessing its returning how many process thats done. so how do i get it to return 4 similar to the COUNT function?
Thanks a lot!!

rs, I'm assuming, is the resultant recordset that your SQL returns? If so, you can do:
rs.MoveFirst
rs.MoveLast
X = rs.RecordCount
X should equal 4 in this case, since you have 4 records in your recordset.
I don't think you want to use "row" as a variable name, as that is a reserved word and will probably cause issues when you try to reference it. Make your life easier and call it "RowX" or something that's not reserved.

Related

need to look through many records of one table for each one in another

In Oracle SQL Developer, I get the error, "ORA-01427: single-row subquery returns more than one row" when I try to run this line of code.
UPDATE stream_log sl
set recordnum =
(SELECT recordnum
FROM STREAM_LOG_HISTORY slh
WHERE substr(slh.recordnum, 2, 5) = sl.recordnum);
In order to try to fix it, I tried changing my code to this:
UPDATE stream_log sl
set recordnum =
(SELECT recordnum
FROM STREAM_LOG_HISTORY slh
WHERE substr(slh.recordnum, 2, 5) = sl.recordnum).first;
but it says the period is syntactically erroneous.
I need to retrieve the first character of strings that match the last 5 of the given one, but to do that I need to look through many records of one table for each one in another. Any advice is appreciated.
I need to retrieve the first character of strings that match the last
5 of the given one,
The "first character" that matches cannot be guaranteed to be a particular string, every time you run the update, unless you have any other unique column which could be used to order the results, preferably using row_number() or FIRST_VALUE functions. So, other option is to use MAX or MIN to get a single record for each match.
UPDATE stream_log sl
SET recordnum = (
SELECT MAX(recordnum)
FROM stream_log_history slh
WHERE Substr(slh.recordnum, 2, 5) = sl.recordnum
);

How to use aggregate function to filter a dataset in ssrs 2008

I have a matrix in ssrs2008 like below:
GroupName Zone CompletedVolume
Cancer 1 7
Tunnel 1 10
Surgery 1 64
ComplatedVolume value is coming by a specific expression <<expr>>, which is equal to: [Max(CVolume)]
This matrix is filled by a stored procedure that I am not supposed to change if possible. What I need to do is that not to show the data whose CompletedVolume is <= 50. I tried to go to tablix properties and add a filter like [Max(Q9Volume)] >= 50, but when I try to run the report it says that aggregate functions cannot be used in dataset filters or data region filters. How can I fix this as easy as possible?
Note that adding a where clause in sql query would not solve this issue since there are many other tables use the same SP and they need the data where CompletedVolume <= 50. Any help would be appreciated.
EDIT: I am trying to have the max(Q9Volume) value on SP, but something happening I have never seen before. The query is like:
Select r.* from (select * from results1 union select * from results2) r
left outer join procedures p on r.pid = p.id
The interesting this is there are some columns I see that does not included by neither results1/results2 nor procedures tables when I run the query. For example, there is no column like Q9Volume in the tables (result1, result2 and procedures), however when I run the query I see the columns on the output! How is that possible?
You can set the Row hidden property to True when [Max(CVolume)] is less or equal than 50.
Select the row and go to Row Visibility
Select Show or Hide based on an expression option and use this expression:
=IIF(
Max(Fields!Q9Volume.Value)<=50,
True,False
)
It will show something like this:
Note maximum value for Cancer and Tunnel are 7 and 10 respectively, so
they will be hidden if you apply the above expression.
Let me know if this helps.

Countif query in access

I am trying to run a query that calculate with a countif function but I am having trouble with it. I have used the count and the iif functions in the builder but I think something weird is going on. I am trying to count the number of times a certain value occurs in a column so I do not want a specific value to equal to if that's possible?
Thanks!
To count the number of times a value appears you can use something like.
If you want to know how many times each value appears just omit the WHERE clause (without a sample of data I've used a table in the database I'm working on).
SELECT ProcessID,
COUNT(ProcessID)
FROM tbl_PrimaryData_Step1
WHERE ProcessID = 4
GROUP BY ProcessID
if you need just the value you can use:
SELECT COUNT(ProcessID)
FROM tbl_PrimaryData_Step1
WHERE ProcessID = 4
GROUP BY ProcessID
Another way is:
SELECT DCOUNT("ProcessID","tbl_PrimaryData_Step1","ProcessID = 4")
Edit:
In reply to your comment on your original post this SQL will give the result you're after:
SELECT Concatenate,
COUNT(Concatenate)
FROM MyTable
GROUP BY Concatenate

rowcount before and after query

Can someone explain the difference between these 2 simple queries ...
SET ROWCOUNT = 10
select * from t_Account order by account_date_last_maintenance
and this one
select * from t_Account order by account_date_last_maintenance
SET ROWCOUNT = 10
when executed both return only 10 rows, but the rows are different. There are millions of rows in the table if that matters. Also, the first query runs consistently 20% longer.
Thanks everyone
When you execute SET ROWCOUNT 10 you are telling SQL to stop the query after 10 results are returned. Your first SQL statement is the correct syntax (with the exception of the first line which should read SET ROWCOUNT 10).
The second statement as written will return all of the values ordered when initially executed and then set the row count to 10, so any subsequent execution will return the first 10 items.
ROWCOUNT must be set to 0 to get things back to "normal" execution.
As to why things were returning differently, the data might not be processed the same every time and given the size of your dataset it is most likely that you might sometimes get matching results, but it is not a sure thing. If you want consistent results and only want the first 10 results I would recommend using TOP.

SQL Server 2008 UPDATE Statement WHERE clause precedence

I wrote the following query:
UPDATE king_in
SET IN_PNSN_ALL_TP_CNTRCT_CD = IN_PNSN_ALL_TP_CNTRCT_CD + '3'
WHERE COALESCE(IN_PNSN_ALL_TP_CNTRCT_TX, '') <> ''
AND CHARINDEX('3', IN_PNSN_ALL_TP_CNTRCT_CD) = 0
It checks to see if a field has a value in it and if it does it puts a 3 in a corresponding field if there isn't a 3 already in it. When I ran it, I got a string or binary data will be truncated error. The field is a VARCHAR(3) and there are rows in the table that already have 3 characters in them but the rows that I was actually doing the updating on via the WHERE filter had a MAX LEN of 2 so I was completely baffled as to why SQL Server was throwing me the truncation error. So I changed my UPDATE statement to:
UPDATE king_in
SET IN_PNSN_ALL_TP_CNTRCT_CD = k.IN_PNSN_ALL_TP_CNTRCT_CD + '3'
FROM king_in k
INNER JOIN
(
SELECT ki.row_key,
in_sqnc_nb
FROM king_in ki
INNER JOIN King_Ma km
ON ki.Row_Key = km.Row_Key
INNER JOIN King_Recs kr
ON km.doc_loc_nb = kr.ACK_ID
WHERE CHARINDEX('3', IN_PNSN_ALL_TP_CNTRCT_CD) = 0
AND COALESCE(IN_PNSN_ALL_TP_CNTRCT_TX, '') <> ''
) a
ON k.Row_Key = a.Row_Key
AND k.in_sqnc_nb = a.insr_sqnc_nb
and it works fine without error.
So it appears based on this that when doing an UPDATE statement without a FROM clause that SQL Server internally goes through and runs the SET statement before it filters the records based on the WHERE clause. Thats why I was getting the truncation error, because even though the records I wanted to update were less than 3 characters, there were rows in the table that had 3 characters in that field and when it couldn't add a '3' to the end of one of those rows, it threw the error.
So after all of that, I've got a handful of questions.
1) Why? Is there a specific DBMS reason that SQL Server wouldn't filter the result set before applying the SET statement?
2) Is this just a known thing about SQL that I never learned along the way?
3) Is there a setting in SQL Server to change this behavior?
Thanks in advance.
1 - Likely because your criteria are not SARGable - that is, they can't use an index. If the query optimizer determines it's faster to do a table scan, it'll go ahead and run on all the rows. This is especially likely when you filter on a function applied to the field like you do here.
2 - Yes. The optimizer will do what it thinks it best. You can get around this somewhat by using parentheses to force an evaluation order of your WHERE clause but in your example I don't think it would help since it forces a table scan regardless.
3 - No, you need to alter your data or your logic to allow indexes to be used. If you really really need to filter on existence of a certain character in a field, it probably should be it's own column and/or you should normalize that particular bit of data better.
A workaround for your particular instance would be to add a WHERE LEN(IN_PNSN_ALL_TP_CNTRCT_CD) < 3 as well.