mysql query conditional ordering precedence - mysql

I have a number of uniquely identified records/rows that are returned as results when selected by their shared identifier. I only want one record/result returned per group. If a given variable belonging to each record is set to a specific value, I want to return that row (which would always be the last instance, if it is set - there is always only one instance of the variable being set for a group of query results). If all the possible rows/results for an instance are reviewed and the variable for that group is not set (meaning the last row returned doesn't have that variable set), then I would want to return the FIRST row result (the first result sorted by a DIFFERENT variable).
so far I have
SELECT table1.var1, table1.var2, table1.var3, table1.var4 etc
from table1, table2
where table1.var1 = table2.var1
AND (condition that satisfies where the variable is set)
OR (condition where the variable isn't set but returns multiple results
that I need the first instance of, but ONLY IF the first condition
doesn't exist in the group of results)
GROUP BY table1.var1, table1.var2 etc
ORDER BY table1.var1, table1.var2 DESC,
table1.variablethatIthoughtwouldsortthesecondconditionbutdoesnt DESC;
I tried using ASC and DESC but the first condition will only be met in the last result, and I would only want the result in the OR condition if the first condition cannot be met - but it has to be the first instance of whatever results match the OR condition.
Any help is appreciated, and I am happy to further clarify if needed.
I'm basically looking for a way to give precedence to the first condition (select the record that whose variable is set if there is one) and select the first instance of the other conditional if it isn't.
In other words, I want any records that meet the first condition (there will only be one per group), and then I also want, from a different group, only the first result per grouping that meets the second condition but whose ID is not in the first group (because the record should only either be in the first group or the second group, not both).

Related

Alteryx to select top N records where N=a value on that group

I'm in a fix with Alteryx. I'm trying to select the top N rows where N=a cell value for that partition. The business question is:
"We need to know, out of our orders (TicketIDs), those that have
least 1 combination of Type of discount item AND drink AND side."
The SQL query would join this table onto itself and partition to get the TopNtoIncludeInItems for that row, however, I just can't seem to find a way to do this in Alteryx. I've tried the community, but the question has gone ananswered.
In other words, select thusly:
<pseudocode>
for each (TicketID)
for each(Type)
select top(TopNtoIncludeInItems for this.TicketID)
next
next
</pseudocode>
or indeed select just the green records
Here's my solution:
MultiRow Formula: create new field ComboCount (or whatever) as Int32, 0 or empty for rows that don't exists, Group By TicketID and Type, with the Expression [Row-1:ComboCount]+1 ... this counts up each group; we'll want the first topN of each group, ensuring the group actuall has that many, and not going beyond TopN.
Filter on [ComboCount] <= [TopN] ... which excludes unnecessary rows beyond TopN
Summarize: group by TicketID and Type, doing Max(ComboCount) ... if this value is less than TopN for any group, the group should be excluded:
Join the summary back to the earlier pre-summary data on TicketID and Type
Filter on [Max_ComboCount] = [TopN] ... this excludes the groups where any ItemType falls short of TopN
And that's it. Pictorally, this is what my workflow looks like, along with data results based on data similar to that in your screenshot:

Why MySQL COUNT without table name gives 1

could you please explain why mysql count function without providing any table name gives 1 as value?
SELECT COUNT(*);
Result: 1
Because in mysql select constant_value command is valid (such as select 2 will return 2) and will return 1 row. Count() function without group by will collapse the resultset and count the number of items in the resultset. In this case 1 row would be returned and count(*) counts that.
Normally all selects are of the form SELECT [columns, scalar computations on columns, grouped computations on columns, or scalar computations] FROM [table or joins of tables, etc]
Because this allows plain scalar computations we can do something like SELECT 1 + 1 FROM SomeTable and it will return a recordset with the value 2 for every row in the table SomeTable.
Now, if we didn't care about any table, but just wanted to do our scalar computed we might want to do something like SELECT 1 + 1. This isn't allowed by the standard, but it is useful and most databases allow it (Oracle doesn't unless it's changed recently, at least it used to not).
Hence such bare SELECTs are treated as if they had a from clause which specified a table with one row and no column (impossible of course, but it does the trick). Hence SELECT 1 + 1 becomes SELECT 1 + 1 FROM ImaginaryTableWithOneRow which returns a single row with a single column with the value 2.
Mostly we don't think about this, we just get used to the fact that bare SELECTs give results and don't even think about the fact that there must be some one-row thing selected to return one row.
In doing SELECT COUNT() you did the equivalent of SELECT COUNT() FROM ImaginaryTableWithOneRow which of course returns 1.
Reference

Does MySQL "SELECT LIMIT 1" with multiple records select first record from the top?

I've searched and searched and can't find an answer to this question, I'm probably asking it in the wrong way.
I am querying an employee database.
I need to get details based on a position id, however there could be multiple records for that position id as this organisation has permanent employees and temporary employees that act against the same position.
So, in order to get the CURRENT occupant of the position id, I need my query to SELECT the FIRST record that matches the position string, from the TOP DOWN.
will this select the first matched record from the top?
SELECT * WHERE `position_id`="00000000" LIMIT 1;
Thanks in advance.
You need an ORDER BY clause to define the ordering between the individual records your table. If you do not use ORDER BY you can assume no fixed order between the records, and you could get a new order each time you executed the query.
From the manual:
With one argument, the value specifies the number of rows to return from the beginning of the result set
So with LIMIT 1 you get the first row from the result set. What the result set is depends on engine used and which indexes you have. If you want the first row added, you need to create another column to define that.
It just gets one at random*. There's no way to tell which one it will be, unless you add an ORDER BY clause.
* Not really at random, of course. It depends on the way the records are stored and repeated queries will probably return the same result every time, at least as long as you don't modify the table or its contents. I actually mean, you cannot be sure.

MySQL Subquery - Returning More Than One Row

I have a table in which there are a listing of names, first and last in a column. So a column, called "manager" could have a value of "John Doe". I want to right a query that simply goes through each row in this table and displays the first letter and last name of the "manager" column. Everything I do comes up with "Subquery returns more than one row".
Starting small, I've just decided to pull the first letter:
SELECT id, LEFT((SELECT manager FROM my_table), 1) FROM my_table;
Or am I just completely off base on this
You're using a subquery to fetch into a field of a parent query. As such, the subquery can return only a single row. think of it this way: a result set is a 2-dimensional construct. a series of columns and rows. The data a subquery returns has to match the physical constraints of the thing it's returning into.
Since you're fetching into a field, that means one SINGLE value. If multiple values were allowed to be returned, you'd effectively be trying to turn your 2D result set into a 3d set (rows + columns plus a skyscraper growing out of one of those fields).
Your query does NOT need to be a subquery at all:
SELECT id, LEFT(manager, 1) AS first_letter FROM yourtable
Also, not that if you want separate first and last names, you would be better off storing those are separate fields. It is very easy to rebuilt a name from a set of first/last name fields, but very very difficult to reliably separate a monolithic name into individual first and last names, e.g.
simple:
John Doe (fn: john, ln: doe)
hard:
Billy Jo Todd (is that "Billy" and "Jo Todd", "Billy" and "Todd" with middle name Jo?
dead simple:
field firstname = John
field lastname = Doe
If you want to use a subquery, this query works as you intend it to, though I am not sure this is the best way to proceed in any case. We would need more information about your needs to assert that.
SELECT
m1.id,
m2.manager
FROM
my_table AS m1 INNER JOIN
(SELECT id, LEFT(manager, 1) AS manager FROM my_table) as m2
ON m1.id = m2.id
http://sqlfiddle.com/#!2/9c395/6
You must add a condition to your subquery to return the row you want to compare like
SELECT manager FROM my_table WHERE id = 1

SQL combine COUNT and AVG query with SELECT

I need to get the average rating and the total number of ratings for a particular user and then select all single ratings (rating_value, rating_text, creator) as well:
$rating_query = mysql_query("SELECT COUNT(1) as rating_count
,AVG(rating_value), rating_value, rating_text, creator
FROM user_rating WHERE rated_user = $user_id");
This query would return the COUNT(1) result and the AVG(rating_value) for every row, but I only need those values once.
Is there any way to do this without making 2 separate queries?
There may be a trick I'm not aware of, but I don't think that's possible to do in a single query. You could try using a GROUP BY clause if that would make sense for you, but I'm guessing it probably doesn't from the column names you're using. Any relation requires a single atomic value at any given row and column, even if that value is null. What you are requesting is that columns 1 and 2 in every row but the first have no value, and again I don't think this is possible.