Creating a third alias from the remainder of two aliases in MYSQL? - mysql

Is it possible to create a third alias from the remainder of two aliases in MYSQL?
Here is my query:
SELECT DISTINCT
workcards.task,
workcards.program,
workcards.zone,
workcards.CYLcomp,
workcards.CYLint,
workcards.task,
workcards.CYLcomp + workcards.CYLint AS nextdue,
workcards.wcnumber,
(SELECT airtimes.total_cycles
FROM airtimes
WHERE airtimes.nnumber='xxxxx'
ORDER BY airtimes.total_cycles DESC LIMIT 1) AS current_cycle
FROM workcards
WHERE basis LIKE '%CYL%'
AND nnumber='xxxxx'
ORDER BY CASE nextdue
WHEN 0 THEN 1 ELSE -1 END ASC, nextdue ASC
What I want to do is create a third alias which would be the difference of the 'nextdue' minus 'current_cyle' aliases? Something like:
nextdue - current_cycle AS remainder?
Sorry if noob or whatever.
Thanks

You cannot use calculations results aliases to use with another calculations in select part (http://dev.mysql.com/doc/refman/5.0/en/problems-with-alias.html). But you can get what you want by rebuilding your query so it will use joins and grouping:
SELECT DISTINCT
w.*,
w.CYLcomp + w.CYLint AS nextdue,
MAX(a.total_cycles) AS current_cycle
w.CYLcomp + w.CYLint - MAX(a.total_cycles) AS reminder
FROM workcards w
JOIN airtimes a ON a.nnumber = w.nnumber
WHERE w.basis LIKE '%CYL%' AND w.nnumber='xxxxx'
GROUP BY w.nnumber
ORDER BY CASE nextdue WHEN 0 THEN 1 ELSE -1 END ASC, nextdue ASC

Related

SQL query - find values that meet m conditions out of n

Is there any way to find values that meet any m conditions out of given n conditions? For instance, if there are 10 conditions, and I want to find values that meet any 2 of them.
Use CASE expressions in the WHERE clause, 1 for each condition like this:
WHERE 2 =
CASE WHEN <condition1> THEN 1 ELSE 0 END +
CASE WHEN <condition2> THEN 1 ELSE 0 END +
CASE WHEN <condition3> THEN 1 ELSE 0 END +
..........................................
You can change the = sign to > or < to meet your requirement.
There is. It's not gonna be pretty though.
Start with your conditions as SELECT expressions.
select T.*,
case
when T.SOME_NUMERIC_COLUMN > 0 then 1
else 0
end IS_POSITIVE,
(select sign(COUNT(*))
from SOME_OTHER_TABLE
where parent_id = T.ID) HAS_CHILDREN
...
from SOME_TABLE T
Design these expression in such a way that you get 1 when a condition is met and 0 when it's not.
Then sum up the score and add a WHERE clause.
SELECT *
FROM (
SELECT R.*,
IS_POSITIVE + HAS_CHILDREN + ... SCORE
FROM (...) R)
WHERE SCORE > 2
Of course you're gonna pay a hefty price in performance for this. You won't be able to use your conditions directly to limit the resultset so I'd expect the execution plans to be extremely disappointing. That said, it's not like what you have in mind is a standard task for RDBMS so it should be enough for a proof of concept.

MySQL ORDER BY CASE + operator

I am trying to do a search that would be sorted by relevance.
Let's say the search term contains 3 words: A, B and C. What I am trying to do is to check if the search term is present in the SELECT result and if yes that would increase its rank.
ORDER BY CASE
(
WHEN search_word_A_is_present THEN +1
WHEN search_word_B_is_present THEN +1
WHEN search_word_C_is_present THEN +1
ELSE 0
END
)
DESC
While there is no syntax error and the search runs and sorts by something (that seems different from what I want) but I am not sure what is being added up if anything. How would I go about seeing what the final rank (sum) is at the end for each result? Is this the correct way to do it?
Since in MySQL boolean conditions result in 1 and 0, you can simply add those up
ORDER BY search_word_A_is_present + search_word_B_is_present + search_word_C_is_present
DESC
A more practical example:
ORDER BY col1 = 1 + col2 = 'A' + col3 = 44 DESC

Grouping mysql by a regex?

I am trying to find the count of how many times a location is used in my table of search results, but I want to group together cases where the same post code area start is used. The following groups purely on the text used:
SELECT count(*),
search_browse_log.postcode_start
FROM search_browse_log
GROUP BY postcode_start
ORDER BY count(*) DESC
But in the data, I have for example CR0, CR1, CR2 (postcode starts). I want to group them all together so I have a count of 3 for "CR", rather than 1 each of CR0, CR1 and CR2.
Thanks in advance if you can help!
Use a conditional in the GROUP BY clause to get either 1 or 2 characters, depending on whether the postcode starts with 1 or 2 letters.
GROUP BY IF(postcode_start REGEXP '^[A-Z][A-Z]',
LEFT(postcode_start, 2),
LEFT(postcode_start, 1))
If it's only the first 2 characters of the postcode, you could use the LEFT function in the group by:
SELECT count(*),
LEFT(postcode_start,2) as `postcode_start`
FROM search_browse_log
GROUP BY LEFT(postcode_start,2)
ORDER BY count() DESC
To group by the non-numeric characters at the start of the string:
SELECT count(*),
IF(postcode_start REGEX '^[a-ZA-Z][0-9]',LEFT(postcode_start,1),LEFT(postcode_start,2)) as `postcode_start`
FROM search_browse_log
GROUP BY IF(postcode_start REGEX '^[a-ZA-Z][0-9]',LEFT(postcode_start,1),LEFT(postcode_start,2))
ORDER BY count() DESC
For reference, see https://dev.mysql.com/doc/refman/5.7/en/regexp.html#operator_regexp

Select Max and Select other column

I am trying to get the max + 1 value from one column, and all of the values from another column. However, my query does not give any results.
For example,
SectionItemID SectionItem
1 blue
2 red
The query should return
SectionItemID SectionItem
3 blue
red
Heres what I have
SELECT SectionItem,MAX(SectionItemID) + 1 AS SectionItemID FROM Core.SectionItem_Lkup
SELECT SectionItem,
(select MAX(SectionItemID)+1 FROM Core.SectionItem_Lkup) AS SectionItemID
FROM Core.SectionItem_Lkup
Whenever you GROUP BY, you should aggregate the other columns involved.
Mysql does allow to omit aggregation on other colums
MsSQL does not, cause the result is undefined for columns without Aggregation.
Best way is to aggregate other columns. For your szenario, you could use group_concat
SELECT MAX(SectionItemID)+1, Group_concat(SectionItem) FROM tbl
Note: The query does not contain any Group By, because you dont want to group on SectionItemId nor SectionItem. Omiting the Group By and using aggregate-functions will use them on the whole table.
Output:
MAX(SECTIONITEMID)+1 GROUP_CONCAT(SECTIONITEM)
3 blue,red
http://sqlfiddle.com/#!2/353bf3/6
select case when t2.SectionItem = 'blue'
then cast(max(t1.SectionItemID) + 1 as varchar(1))
else '' end
as SectionItemID
, t2.SectionItem
from Core.SectionItem_Lkup t1
full outer join Core.SectionItem_Lkup t2 on 1 = 1
group by t2.SectionItem
order by
case when t2.SectionItem = 'blue'
then cast(max(t1.SectionItemID) + 1 as varchar(1))
else '' end
desc

MySql: Fetch LIMITED results using GROUP BY clause on one table/view

I have a view 'view_type' like:
type------name------fid
type_a----name1-----12
type_a----name2-----27
type_a----name3-----45
type_a----name4-----43
type_a----name5-----25
type_a----name7-----75
type_a----name6-----15
type_b----bame1-----12
type_b----bame2-----27
type_b----bame3-----45
type_b----bame4-----43
type_b----bame5-----25
type_c----came7-----55
type_c----came6-----25
Now i want to fetch results having 'ame' in name field, but only from 'type_a' & 'type_b' and also only 4results from each.
type------name------fid
type_a----name1-----12
type_a----name2-----27
type_a----name3-----45
type_a----name4-----43
type_b----bame1-----12
type_b----bame2-----27
type_b----bame3-----45
type_b----bame4-----43
In simple words I want to limit results of 'group by' result set.
Don't want to use 'complex sub query' OR 'stored procedure'. Is there any simple query which help me out?
Try this query
select * from view_type where type = 'type_a' and name regexp 'ame' LIMIT 4
UNION
select * from view_type where type = 'type_b' and name regexp 'ame' LIMIT 4