What is MySQL equivalent of MS Access LAST()? - mysql

I have no idea what the following query means as I do not have any exposure to MS Access. I need to convert it into MySQL and I can't figure out what does the LAST() does
SELECT
Containers.Container_No,
Max(Containers.LastOfContainer_Date),
Max(Containers.LastOfContainer_Time),
Last(Containers.LastOfETD),
Last(Containers.LastOfContainer_Status),
Last(Containers.LastOfPickup_From),
Last(Containers.LastOfPickup_To),
Last(Containers.LastOfConsignee_Name),
Last(Containers.LastOfContract_No),
Last(Containers.LastOfSeaLNo)
FROM
Containers
WHERE
Containers.Customer_Name = 'value here"
AND
Containers.LastOfContainer_Date >='Date here'
AND
Containers.LastOfContainer_Date <= 'Date here'
GROUP BY
Containers.Container_No
Can some one explain me what does this LAST() actually do?
UPDATE
It seems the query can be changed to following:
SELECT
Containers.Container_No,
Max(Containers.LastOfContainer_Date),
Max(Containers.LastOfContainer_Time),
Containers.LastOfETD,
Containers.LastOfContainer_Status,
Containers.LastOfPickup_From,
Containers.LastOfPickup_To,
Containers.LastOfConsignee_Name,
Containers.LastOfContract_No,
Containers.LastOfSeaLNo
FROM
Containers
WHERE
Containers.Customer_Name = '".$customername."'
AND
Containers.LastOfContainer_Date >='".$fromdate."'
AND
Containers.LastOfContainer_Date <= '".$todate."'
GROUP BY
Containers.Container_No
order by
Containers.LastOfETD,
Containers.LastOfContainer_Status,
Containers.LastOfPickup_From,
Containers.LastOfPickup_To,
Containers.LastOfConsignee_Name,
Containers.LastOfContract_No,
Containers.LastOfSeaLNo

The Last function returns the last value on a given query, for instance I assume that in the query you are using it would return the data of the last transaction made by that certain customer,
for instance lets say Mike Jagger bought 2things today, he will have 2 transactions with the same date, if you use the last function you would get the latest information that was inserted.
ID | Date | Product
1 12/12/2011 socks
2 12/12/2011 shirt
select last(product)
from buys;
it would output : shirt
BTW to emulate this behavior you might want to use
ORDER BY product DESC LIMIT 1

According to this page, "The Last function returns the last value from the result set of a query."
You might have to do some kind of ORDER BY x DESC LIMIT 1.

Related

How to insert SUM() function that sums rows with similar ID in a code part of witch is unchangeable?

I am trying to write a quarry in a module for Dolibarr ERP. But module hase a part of code that is predefined and can not be changed. And I need to insert a SUM() function in it that will combine rows with similar id. That i know how to do in a regular MySQL:
SELECT fk_product AS prod, SUM(value) AS qty
FROM llx_stock_mouvement
WHERE type_mouvement = 2 AND label LIKE 'SH%'
GROUP BY fk_product
ORDER BY 1 DESC
LIMIT 26
that gives me what I want :
prod qty
1 13
2 10
BUT module has a predefined unchangeable code :
this part is predefined module writes it himself based on values provider in it:
SELECT DISTINCT
c.fk_product AS com,
c.value AS qty
THIS PART I CAN WRITE IN A MODULES GUI:
FROM
llx_stock_mouvement AS c
WHERE
type_mouvement = 2
AND label LIKE 'SH%'
And this part is predefined:
ORDER BY 1 DESC
LIMIT 26
I would appreciate any help and advice on question is there any workaround that can be done to make my desired and result ampere ? As it would using the first code I posted ?
If you can only modify the bit in the middle box then you might need to use a subquery;
--fixed part
SELECT DISTINCT
c.fk_product AS com,
c.value AS qty
--begin your editable part
FROM
(
SELECT fk_product,
SUM(value) AS value
FROM llx_stock_mouvement
WHERE type_mouvement = 2 AND label LIKE 'SH%'
GROUP BY fk_product
) c
--end your editable part
--fixed part
ORDER BY 1
DESC
LIMIT 26

How to Find First Valid Row in SQL Based on Difference of Column Values

I am trying to find a reliable query which returns the first instance of an acceptable insert range.
Research:
some of the below links adress similar questions, but I could get none of them to work for me.
Find first available date, given a date range in SQL
Find closest date in SQL Server
MySQL difference between two rows of a SELECT Statement
How to find a gap in range in SQL
and more...
Objective Query Function:
InsertRange(1) = (StartRange(i) - EndRange(i-1)) > NewValue
Where InsertRange(1) is the value the query should return. In other words, this would be the first instance where the above condition is satisfied.
Table Structure:
Primary Key: StartRange
StartRange(i-1) < StartRange(i)
StartRange(i-1) + EndRange(i-1) < StartRange(i)
Example Dataset
Below is an example User table (3 columns), with a set range distribution. StartRanges are always ordered in a strictly ascending way, UserID are arbitrary strings, only the sequences of StartRange and EndRange matters:
StartRange EndRange UserID
312 6896 user0
7134 16268 user1
16877 22451 user2
23137 25142 user3
25955 28272 user4
28313 35172 user5
35593 38007 user6
38319 38495 user7
38565 45200 user8
46136 48007 user9
My current Query
I am trying to use this query at the moment:
SELECT t2.StartRange, t2.EndRange
FROM user AS t1, user AS t2
WHERE (t1.StartRange - t2.StartRange+1) > NewValue
ORDER BY t1.EndRange
LIMIT 1
Example Case
Given the table, if NewValue = 800, then the returned answer should be 23137. This means, the first available slot would be between user3 and user4 (with an actual slot size = 813):
InsertRange(1) = (StartRange(i) - EndRange(i-1)) > NewValue
InsertRange = (StartRange(6) - EndRange(5)) > NewValue
23137 = 25955 - 25142 > 800
More Comments
My query above seemed to be working for the special case where StartRanges where tightly packed (i.e. StartRange(i) = StartRange(i-1) + EndRange(i-1) + 1). This no longer works with a less tightly packed set of StartRanges
Keep in mind that SQL tables have no implicit row order. It seems fair to order your table by StartRange value, though.
We can start to solve this by writing a query to obtain each row paired with the row preceding it. In MySQL, it's hard to do this beautifully because it lacks the row numbering function.
This works (http://sqlfiddle.com/#!9/4437c0/7/0). It may have nasty performance because it generates O(n^2) intermediate rows. There's no row for user0; it can't be paired with any preceding row because there is none.
select MAX(a.StartRange) SA, MAX(a.EndRange) EA,
b.StartRange SB, b.EndRange EB , b.UserID
from user a
join user b ON a.EndRange <= b.StartRange
group by b.StartRange, b.EndRange, b.UserID
Then, you can use that as a subquery, and apply your conditions, which are
gap >= 800
first matching row (lowest StartRange value) ORDER BY SB
just one LIMIT 1
Here's the query (http://sqlfiddle.com/#!9/4437c0/11/0)
SELECT SB-EA Gap,
EA+1 Beginning_of_gap, SB-1 Ending_of_gap,
UserId UserID_after_gap
FROM (
select MAX(a.StartRange) SA, MAX(a.EndRange) EA,
b.StartRange SB, b.EndRange EB , b.UserID
from user a
join user b ON a.EndRange <= b.StartRange
group by b.StartRange, b.EndRange, b.UserID
) pairs
WHERE SB-EA >= 800
ORDER BY SB
LIMIT 1
Notice that you may actually want the smallest matching gap instead of the first matching gap. That's called best fit, rather than first fit. To get that you use ORDER BY SB-EA instead.
Edit: There is another way to use MySQL to join adjacent rows, that doesn't have the O(n^2) performance issue. It involves employing user variables to simulate a row_number() function. The query involved is a hairball (that's a technical term). It's described in the third alternative of the answer to this question. How do I pair rows together in MYSQL?

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

MYSQL multiply column value by value in previous row

I hope I can phrase this properly - I'm not sure I've been approaching this correctly.
I am running a MySQLi query for which I need to order the results by the result of a sum (multiplicaiton) of the values in one column. The values are to 2 decimal places and are 'odds' for sporting results. As Such i can not simply sum the values from each row as the result (e.g. 1,1,1 adds to 3 but multiplies to 1) does not give me 'correct' ordering.
At present i am simply performing a sum in my query
SUM(Fav_odds) AS Total
But i'm stumped how i can get 'Total' to be the result of 'Fav_odds * number of rows' in my query.
Fav_odds | Vendor
------------------
1.2 | Name
2.1 | Name
3.2 | Name
So for Vendor called 'Name' i would like to give a multipled value for items in Fav_odds column (e.g. 1.2 * 2.1 * 3.2 = 8.064)
select round(EXP(SUM(LOG(fav_odds))),3) as fav_odds from table;
use a variable
set #miller := 1;
select orderingTotal from
(select #miller:=#miller*Fav_odds as orderingTotal
from mytable) mytotaltable
order by orderingTotal;
or it could be a matter of just saying
sum(Fav_odds) * count(Fav_odds)
if what you are saying at the end is the right way ("fav_total * the number of rows").

Remove order by of IN(1 2 10 5 5 )?

The following query works, but MySQL sorts the results set:
SELECT STRINGTEXT FROM WEBSTRINGS WHERE GUI=0 AND LANGID='GB' AND TOKENID IN
(312,47,48,49,50,51,52,53,54,55,56,57,58,60,61,62, 63,87,88,89,90,208,210,249,309,310,311);
This means that when I grab this in my recordset the data for TOKENID 312 is
at the end rather than being the first one, eg
I expected my resultset to come back in the following order of requests:
312,47,48,49,50,51,52,53,54,55,56,57,58,60,61,62,6 3,87,88,89,90,208,210,249,309,310,311
but it comes back as:
47,48,49,50,51,52,53,54,55,56,57,58,60,61,62,63,87 ,88,89,90,208,210,249,309,310,311,312
Is there anyway to get MySQL to not do this for this query? I really need
them to come back as is.
Try using 'ORDER BY FIELD`
SELECT STRINGTEXT
FROM WEBSTRINGS
WHERE GUI=0 AND LANGID='GB' AND TOKENID IN (312,47,48,49,50,51,52,53,54,55,56,57,58,60,61,62, 63,87,88,89,90,208,210,249,309,310,311)
ORDER BY FIELD (TOKENID,312,47,48,49,50,51,52,53,54,55,56,57,58,60,61,62,6 3,87,88,89,90,208,210,249,309,310,311)
SELECT STRINGTEXT
FROM WEBSTRINGS
WHERE GUI=0
AND LANGID='GB'
AND TOKENID IN (312,47,48,49,50,51,52,53,54,55,56,57,58,60,61,62,63,87,88,89,90,208,210,249,309,310,311);
ORDER BY FIELD(TOKENID,312,47,48,49,50,51,52,53,54,55,56,57,58,60,61,62,63,87,88,89,90,208,210,249,309,310,311);
field documentation: http://dev.mysql.com/doc/refman/5.6/en/string-functions.html#function_field