To Fetch Top 2000 Records - ms-access

I have following query
strfinal = "
TRANSFORM Format(Sum([Mandays].[Hours]),""#0.0"") AS [The Value]
SELECT
Mandays.WorkTypeCode AS WONo,
Format(Sum([Mandays].[Hours]),""0000.0"") AS Total
FROM Mandays
GROUP BY Mandays.WorkTypeCode
PIVOT UCase([Ent By]); "
the query returns more than 2048 records and then it is not possible to show in VB6 MSHFLexGrid(Limit is 2048).
How do I change query so that top 2000 records must be fetched?

The most efficient way will be to do it like this:
CurrentDB.CreateQueryDef("tmpQuery", "SELECT Top 2000 * FROM Mandays")
strfinal = "TRANSFORM Format(Sum([tmpQuery].[Hours]),""#0.0"") AS [The Value]
SELECT tmpQuery.WorkTypeCode AS WONo, Format(Sum([tmpQuery].[Hours]),""0000.0"") AS
Total FROM tmpQuery GROUP BY tmpQuery.WorkTypeCode PIVOT UCase([Ent By]); "
You could put "Top 2000" after the SELECT statement in your current code, but doing it in another query will speed things up quite a bit.
If you like, you can also put an ORDER BY statement in the CreateQueryDef so you can control which 2000 records are used.

Related

MS Access Restart Number Sequence

trying to do a sequence count in MS Access where the count sequence resets based on another field, so example below, trying to figure out ColB:
ColA ColB
4566 1
5677 1
5677 2
5677 3
8766 1
8766 2
1223 1
Think it might have something to do with the DCount() function, unsure. Would very much appreciate the help ... Thanks!
Calculating a group sequence number in Access query is fairly common topic. Requires a unique identifier field, autonumber should serve.
Using DCount():
SELECT *, DCount("*", "table", "ColA=" & [ColA] & " AND ID<" & ID) + 1 AS GrpSeq FROM table;
Or with correlated subquery:
SELECT *, (SELECT Count(*) FROM table AS D WHERE D.ColA=table.ColA AND D.ID<table.ID)+1 AS GrpSeq FROM table;
An alternative to calculating in query is to use RunningSum property of textbox on a Report with Sorting & Grouping settings.

unpaid monthly salaries (mysql +vb.net)

I have a MySQL table some thing like that
NAME salary amount month 1 month 2 month 3 month 4
john 300 300 300 0 0
maria 400 400 0 0 0
tom 380 380 380 380 0
I wanna see results in table or list view or whatever like that
name unpaid month salary amount
john month 3 300
john month 4 300
maria month 2 400
maria month 3 400
maria month 4 400
tom month 4 380
I tried code like:
sql1="select name,month1 from table where month1=0 "
sql2="select name,month2 from table where month2=0"
sql3="select name,month3 from table where month3=0"
sql4="select name,month4 from table where month4=0"
Dim Sql = String.Concat(sql1, ";", sql2 ,";",sql2,";",sql4 )
but didn't work , any help pls ?
The syntax looks a little off in your code that you have now. I do not know if this is the exact code that you have in your program, but when the SQL statements are not properly formatted nothing will happen. I have made some changes to show what may be the issue.
sql1="SELECT name, month1, amount FROM table WHERE month1=0"
sql2="SELECT name, month2, amount FROM table WHERE month2=0"
sql3="SELECT name, month3, amount FROM table WHERE month3=0"
sql4="SELECT name, month4, amount FROM table WHERE month4=0"
Dim Sql = String.Concat(sql1, ";", sql2 ,";",sql2,";",sql4 )
The issue that I see with your current formatting is that you may want to have two separate tables for the name and the pay. With the separate tables you could then use foreign keys and join the two tables to have each name on every month with the amount they were paid that month. You would also be able to group the users based off of their name using GROUP BY
With the restructured table your call would be as simple as the statement below. Since I do not know your table names I have made fake ones for them.
Dim Sql = "SELECT NameTable.name, MonthTable.month, MonthTable.amount
FROM NameTable INNER JOIN MonthTable
ON {prmarykey for name} = {foreign key for month}
GROUP BY NameTable.name"
This should give you the result that you are looking for. Let me know if you have any questions or need clarification.
Try the UNION mysql aggregate :
sql1="select name,month1 as unpaid_month from table where month1=0 "
sql2="select name,month2 as unpaid_month from table where month2=0"
sql3="select name,month3 as unpaid_month from table where month3=0"
sql4="select name,month4 as unpaid_month from table where month4=0"
Dim Sql = String.Concat(sql1, " UNION ", sql2 ,"UNION ",sql2," UNION ",sql4
How you could use spaces before column names.
I would suggest you to use UNION.
But, here's the least version of SQL;
sql = "SELECT NAME, month1 as unpaid_month, salary_amount FROM tablename WHERE month1 = 0"
sql = sql & " UNION "
sql = sql & "SELECT NAME, month2 as unpaid_month, salary_amount FROM tablename WHERE month2 = 0"
sql = sql & " UNION "
sql = sql & "SELECT NAME, month3 as unpaid_month, salary_amount FROM tablename WHERE month3 = 0"
sql = sql & " UNION "
sql = sql & "SELECT NAME, month4 as unpaid_month, salary_amount FROM tablename WHERE month4 = 0"
But, the query is not good enough. What will happen if someone is paid half of its salary. And why you should get more than one record for a single person? Shouldn't there be any SUM for salary_amount and string concatenation for unpaid_month?
As it wasn't the part of your question, I can't post the advanced SQL here. Please ask for it in comment if you want that.
Please read these functions SUM() and GROUP_CONCAT() with temporary table AS TABLE. I think that you should use them for good programming.

MySQL match area code only when given the full number

I have a database that lists a few area codes, area code + office codes and some whole numbers and a action. I want it to return a result by the digits given but I am not sure how to accomplish it. I have some MySQL knowledge but its not very deep.
Here is a example:
match | action
_____________________
234 | goto 1
333743 | goto 2
8005551212| goto 3
234843 | goto 4
I need to query the database with a full 10 digit number -
query 8005551212 gives "goto 3"
query 2345551212 gives "goto 1"
query 3337431212 gives "goto 2"
query 2348431212 gives "goto 4"
This would be similar to the LIKE selection, but I need to match against the database value instead of the query value. Matching the full number is easy,
SELECT * FROM database WHERE `match` = 8005551212;
First the number to query will always be 10 digits, so I am not sure how to format the SELECT statement to differentiate the match of 234XXXXXXX and 234843XXXX, as I can only have one match return. Basically if it does not match the 10 digits, then it checks 6 digits, then it will check the 3 digits.
I hope this makes sense, I do not have any other way to format the number and it has to be accomplished with just a single SQL query and return over a ODCB connection in Asterisk.
Try this
SELECT match, action FROM mytable WHERE '8005551212' like concat(match,'%')
The issue is that you will get two rows in one case .. given your data..
SELECT action
FROM mytable
WHERE '8005551212' like concat(match,'%')
order by length(match) desc limit 1
That should get the row that had the most digits matched..
try this:
SELECT * FROM (
SELECT 3 AS score,r.* FROM mytable r WHERE match LIKE CONCAT(SUBSTRING('1234567890',1,3),'%')
UNION ALL
SELECT 6 AS score,r.* FROM mytable r WHERE match LIKE CONCAT(SUBSTRING('1234567890',1,6),'%')
UNION ALL
SELECT 10 AS score,r.* FROM mytable r WHERE match LIKE CONCAT(SUBSTRING('1234567890',1,10),'%')
) AS tmp
ORDER BY score DESC
LIMIT 1;
What ended up working -
SELECT `function`,`destination`
FROM reroute
WHERE `group` = '${ARG2}'
AND `name` = 0
AND '${ARG1}' LIKE concat(`match`,'%')
ORDER BY length(`match`) DESC LIMIT 1

Select data which have same letters

I'm having trouble with this SQL:
$sql = mysql_query("SELECT $menucompare ,
(COUNT($menucompare ) * 100 / (SELECT COUNT( $menucompare )
FROM data WHERE $ww = $button )) AS percentday FROM data WHERE $ww >0 ");
$menucompare is table fields names what ever field is selected and contains data bellow
$button is the week number selected (lets say week '6')
$ww table field name with row who have the number of week '6'
For example, I have data in $menucompare like that:
123456bool
521478bool
122555heel
147788itoo
and I want to select those, who have same word in the last of the data and make percentage.
The output should be like that:
bool -- 50% (2 entries)
heel -- 25% (1 entry)
itoo -- 25% (1 entry)
Any clearness to my SQL will be very appreciated.
I didn't find anything like that around.
Well, keeping data in such format probably not the best way, if possible, split the field into 2 separate ones.
First, you need to extract the string part from the end of the field.
if the length of the string / numeric parts is fixed, then it's quite easy;
if not, you should use regular expressions which, unfortunately, are not there by default with MySQL. There's a solution, check this question: How to do a regular expression replace in MySQL?
I'll assume, that numeric part is fixed:
SELECT s.str, CAST(count(s.str) AS decimal) / t.cnt * 100 AS pct
FROM (SELECT substr(entry, 7) AS str FROM data) AS s
JOIN (SELECT count(*) AS cnt FROM data) AS t ON 1=1
GROUP BY s.str, t.cnt;
If you'll have regexp_replace function, then substr(entry, 7) should be replaced to regexp_replace(entry, '^[0-9]*', '') to achieve the required result.
Variant with substr can be tested here.
When sorting out problems like this, I would do it in two steps:
Sort out the SQL independently of the presentation language (PHP?).
Sort out the parameterization of the query and the presentation of the results after you know you've got the correct query.
Since this question is tagged 'SQL', I'm only going to address the first question.
The first step is to unclutter the query:
SELECT menucompare,
(COUNT(menucompare) * 100 / (SELECT COUNT(menucompare) FROM data WHERE ww = 6))
AS percentday
FROM data
WHERE ww > 0;
This removes the $ signs from most of the variable bits, and substitutes 6 for the button value. That makes it a bit easier to understand.
Your desired output seems to need the last four characters of the string held in menucompare for grouping and counting purposes.
The data to be aggregated would be selected by:
SELECT SUBSTR(MenuCompare, -4) AS Last4
FROM Data
WHERE ww = 6
The divisor in the percentage is the count of such rows, but the sub-stringing isn't necessary to count them, so we can write:
SELECT COUNT(*) FROM Data WHERE ww = 6
This is exactly what you have anyway.
The divdend in the percentage will be the group count of each substring.
SELECT Last4, COUNT(Last4) * 100.0 / (SELECT COUNT(*) FROM Data WHERE ww = 6)
FROM (SELECT SUBSTR(MenuCompare, -4) AS Last4
FROM Data
WHERE ww = 6
) AS Week6
GROUP BY Last4
ORDER BY Last4;
When you've demonstrated that this works, you can re-parameterize the query and deal with the presentation of the results.

MySQL: LIMIT by a percentage of the amount of records?

Let's say I have a list of values, like this:
id value
----------
A 53
B 23
C 12
D 72
E 21
F 16
..
I need the top 10 percent of this list - I tried:
SELECT id, value
FROM list
ORDER BY value DESC
LIMIT COUNT(*) / 10
But this doesn't work. The problem is that I don't know the amount of records before I do the query. Any idea's?
Best answer I found:
SELECT*
FROM (
SELECT list.*, #counter := #counter +1 AS counter
FROM (select #counter:=0) AS initvar, list
ORDER BY value DESC
) AS X
where counter <= (10/100 * #counter);
ORDER BY value DESC
Change the 10 to get a different percentage.
In case you are doing this for an out of order, or random situation - I've started using the following style:
SELECT id, value FROM list HAVING RAND() > 0.9
If you need it to be random but controllable you can use a seed (example with PHP):
SELECT id, value FROM list HAVING RAND($seed) > 0.9
Lastly - if this is a sort of thing that you need full control over you can actually add a column that holds a random value whenever a row is inserted, and then query using that
SELECT id, value FROM list HAVING `rand_column` BETWEEN 0.8 AND 0.9
Since this does not require sorting, or ORDER BY - it is O(n) rather than O(n lg n)
You can also try with that:
SET #amount =(SELECT COUNT(*) FROM page) /10;
PREPARE STMT FROM 'SELECT * FROM page LIMIT ?';
EXECUTE STMT USING #amount;
This is MySQL bug described in here: http://bugs.mysql.com/bug.php?id=19795
Hope it'll help.
I realize this is VERY old, but it still pops up as the top result when you google SQL limit by percent so I'll try to save you some time. This is pretty simple to do these days. The following would give the OP the results they need:
SELECT TOP 10 PERCENT
id,
value
FROM list
ORDER BY value DESC
To get a quick and dirty random 10 percent of your table, the following would suffice:
SELECT TOP 10 PERCENT
id,
value
FROM list
ORDER BY NEWID()
I have an alternative which hasn't been mentionned in the other answers: if you access from any language where you have full access to the MySQL API (i.e. not the MySQL CLI), you can launch the query, ask how many rows there will be and then break the loop if it is time.
E.g. in Python:
...
maxnum = cursor.execute(query)
for num, row in enumerate(query)
if num > .1 * maxnum: # Here I break the loop if I got 10% of the rows.
break
do_stuff...
This works only with mysql_store_result(), not with mysql_use_result(), as the latter requires that you always accept all needed rows.
OTOH, the traffic for my solution might be too high - all rows have to be transferred.