SQL (Mysql) order problem - sql

I have the following query:
SELECT a.field_eventid_key_value, a.field_showdate_value, b.nid , c.nid AS CNID
FROM content_type_vorfuehrung AS a
LEFT JOIN content_type_movies as b ON a.field_eventid_key_value = b.field_eventid_value
LEFT JOIN content_type_sonderveranstaltung as c ON a.field_eventid_key_value = c.field_sonderveranstaltungid_value
WHERE /* something */
GROUP BY a.field_eventid_key_value, a.field_showdate_value,
ORDER BY a.field_showdate_value ASC,a.field_showtime_value ASC
(where clause removed since it's irrelevant to the question)
This pulls data from 3 different tables and sorts it according to the "showdate" field in the first table. This is used in a PHP function that returns an array with the results.
Now there is a new requirement: The table "content_type_movies" in this query has a field that's supposed to be a boolean (actually it's an int with a value of either "0" oder "1"). This field is supposed to override the chronological ordering - that is, results where the field is "true" (or "1" respectively) should appear at the beginning of the result array (with the remaining entries ordered chronologically as before).
Is this at all possible with a single query ?
Thank you in advance for your time,
eike

You can use:
ORDER BY b.MyIntField DESC,
a.field_showdate_value,
a.field_showtime_value
where MyIntField is the field that is either 1 or 0 that you want to sort first.

ORDER BY a.content_type_movies DESC, /*then other fields*/ a.field_showdate_value ASC,a.field_showtime_value ASC
that should place all rows with content_type_movies=1 first then others.

Related

How to determine the order of the result from my postgres query?

I have the following query:
SELECT
time as "time",
case
when tag = 'KEB1.DB_BP.01.STATUS.SOC' THEN 'SOC'
when tag = 'KEB1.DB_BP.01.STATUS.SOH' THEN 'SOH'
end as "tag",
value as "value"
FROM metrics
WHERE
("time" BETWEEN '2021-07-02T10:39:47.266Z' AND '2021-07-09T10:39:47.266Z') AND
(container = '1234') AND
(tag = 'KEB1.DB_BP.01.STATUS.SOC' OR tag = 'KEB1.DB_BP.01.STATUS.SOH')
GROUP BY 1, 2, 3
ORDER BY time desc
LIMIT 2
This is giving me the result:
Sometimes the order changes of the result changes from SOH -> SOC or from SOC -> SOH. I'm trying to modify my query so I always get SOH first and than SOC.. How can I achieve this?
You have two times that are identical. The order by is only using time as a key. When the key values are identical, the resulting order for those keys is arbitrary and indeterminate. In can change from one execution to the next.
To prevent this, add an additional column to the order by so each row is unique. In this case that would seem to be tag:
order by "time", tag
You want to show the two most recent rows. In your example these have the same date/time but they can probably also differ. In order to find the two most recent rows you had to apply an ORDER BY clause.
You want to show the two rows in another order, however, so you must place an additional ORDER BY in your query. This is done by selecting from your query result (i.e. putting your query into a subquery):
select *
from ( <your query here> ) myquery
order by tag desc;
Try this:
order by 1 desc, 2
(order by first column descending and by the second column)

Why are queries these not equivalent? (correlated subquery vs. group by)

Why are these two SQL queries not equivalent? One uses a correlated subquery, the other uses group by. The first produces a little over 51000 rows from my database, the second nearly 66000. In both cases, I am simply trying to return all the parts meeting the stated condition, current revision only. A comparison of the output files shows that method #1 (oracle_test1.txt) fails to return quite a few values. Based on that, I can only assume that method #2 is correct. I have some code that has used method #1 for a long time, but it appears I will have to change it. My reasoning concerning the correlated subquery was that as the inner select is comparing the columns in the self join, it will find the max vaule for the prev value for all matches; then return that max prev value for use in the outer query. I designed that query long ago before becoming familiar with the use of group by. Any insights would be appreciated.
Query #1
select pobj_name, prev
from pfmc_part
where pmodel in ('PN-DWG', 'NO-DWG') and pstatus = 'RELEASED'
and prev = (select max(prev) from pfmc_part a where a.pobj_name = pfmc_part.pobj_name)
order by pobj_name, prev"
Query #2
select pobj_name, max(prev) prev
from pfmc_part
where pmodel in ('PN-DWG', 'NO-DWG') and pstatus = 'RELEASED'
group by pobj_name
order by pobj_name, prev"
Sample output:
Query #2 Query #1
P538512 B P538512 B
P538513 A P538513 A
P538514 C P538514 C
P538520 B
P538522 B P538522 B
P538525 A P538525 A
P538531 C P538531 C
P538533 A P538533 A
P538538 B
P538541 B
P538542 B
P538553 A P538553 A
P538569 A P538569 A
Query 1 is returning each of the max ids and then those that have a pmodel of the type specified within your where clause.
Whereas query 2 is selecting all items with a pmodel of the type specified in your where clause and each of the max ids of that.
You may have data which isn't the max id which satisfies your where clause in query 2 which is why it's being omitted in query 1
There are two differences and the rest of the answers focus on one. The "easy" difference is that the max() in the group by is affected by the filter clause. The max() in the other query has no filter, and so it might return no rows (when max(prev) is on a row otherwise filtered out by the where conditions).
In addition, the where version of the query might return duplicate rows when there are multiple rows with the same value of max(prev) for a given pobj_name. The group by will never return duplicate rows.
this query
select pobj_name, prev
from pfmc_part
where pmodel in ('PN-DWG', 'NO-DWG') and pstatus = 'RELEASED'
and prev = (select max(prev) from pfmc_part a where a.pobj_name = pfmc_part.pobj_name)
order by pobj_name, prev"
has a where clause declaration causing it to return less rows -- specifically, only rows where prev = (subquery). that and prev makes it entirely different, and also assigns the value into prev in the first line
if you wanted them to be the more similar, you'd need to modify it like so
select pobj_name, prev, maxes.max
from pfmc_part
JOIN (select max(prev) as max from pfmc_part a where a.pobj_name = pfmc_part.pobj_name) maxes
where pmodel in ('PN-DWG', 'NO-DWG') and pstatus = 'RELEASED'
order by pobj_name, prev"
In query 1 you are ONLY selecting the rows whose prev field is equal to the max(prev) and in query 2 you are selecting all records ALONG WITH max(prev) that's meeting the conditions in the where and group by clause.
Basically, query 1 and query 2 have completely different where clauses. Hope this explains the missing records from query 1.
Your query #1 will certainly fail to return a row for a given pobj_name where maximum prev for that name does not correspond to a revision currently in the database. That could perhaps happen if a revision was skipped or if its row was deleted.
Your Query #2 does not suffer Query #1's limitation, and it may perform better on account of avoiding a correlated subquery. It would be inappropriate, however, if you wanted more data than just pobj_name and aggregate functions of the groups. And by the way, there's no point in including prev in the ORDER BY clause, since pobj_name will already be unique to each result row.
Overall, if the two queries happen to return similar results then that is a matter of the details of the data, not of the queries. They arrive at their results completely differently.

What does ORDER BY 5 DESC mean?

SELECT Departamentos.Nome_Dep,
Funcionarios.Nome AS Funcionario,
Funcionarios.Salario,
AVG(Funcionarios.Salario) OVER(PARTITION BY Departamentos.Nome_Dep) "Média por Departamento"
Salario - AVG(Funcionarios.Salario) OVER(PARTITION BY Departamentos.Nome_Dep) "Diferença de Salário" FROM Funcionarios
INNER JOIN Departamentos
ON Funcionarios.ID_Dep = Departamentos.ID
ORDER BY 5 DESC
The Order By 5 is throwing me off. I've never anything like it. Order By [colunmname] yes, but Order By [number], never seen before. I pulled this off an article.
Note: This is T-SQL.
Source: Window Functions in SQL Server 2005, 2008, 2012
This will order by the 5th field in this SELECT statement
Order by the 5th column in the result set.
The number represents the index of the column within your select list.
Source: http://mattberseth.com/blog/2007/05/quick_tip_order_by_1_descendin.html
Order by fifth column in the result set descending.
It is the SORTING BY RELATIVE POSITION.
You can use the SQL ORDER BY clause to sort by relative position in the result set, where the first field in the result set is 1. The next field is 2, and so on.
Here in this case Order by 5th field in the result set.
Go through http://www.techonthenet.com/sql/order_by.php
about sql order by.
Useful when a similar column name has become a calcuated output field,
In the following example, it would be confusing if say 'order by numberofVioation' as this column name has just become the name of a query output SUM field (of the same old column data)
So it become useful in calculated output field
Example:
Original fields:
name| Type| RiskLevel| Date| results| violations|
/* now add an extra Sum of Violation for each type, pls note 'order by 2 desc' refers to order by the 2nd queried column, ie hi to low */
select Type, sum(numberOfViolations) as numberOfViolations
from restaurantsTable
group by Type
order by 2 desc
Order by 5th field in the result set.

Oracle Group by issue

I have the below query. The problem is the last column productdesc is returning two records and the query fails because of distinct. Now i need to add one more column in where clause of the select query so that it returns one record. The issue is that the column i need
to add should not be a part of group by clause.
SELECT product_billing_id,
billing_ele,
SUM(round(summary_net_amt_excl_gst/100)) gross,
(SELECT DISTINCT description
FROM RES.tariff_nt
WHERE product_billing_id = aa.product_billing_id
AND billing_ele = aa.billing_ele) productdescr
FROM bil.bill_sum aa
WHERE file_id = 38613 --1=1
AND line_type = 'D'
AND (product_billing_id, billing_ele) IN (SELECT DISTINCT
product_billing_id,
billing_ele
FROM bil.bill_l2 )
AND trans_type_desc <> 'Change'
GROUP BY product_billing_id, billing_ele
I want to modify the select statement to the below way by adding a new filter to the where clause so that it returns one record .
(SELECT DISTINCT description
FROM RRES.tariff_nt
WHERE product_billing_id = aa.product_billing_id
AND billing_ele = aa.billing_ele
AND (rate_structure_start_date <= TO_DATE(aa.p_effective_date,'yyyymmdd')
AND rate_structure_end_date > TO_DATE(aa.p_effective_date,'yyyymmdd'))
) productdescr
The aa.p_effective_date should not be a part of GROUP BY clause. How can I do it? Oracle is the Database.
So there are multiple RES.tariff records for a given product_billing_id/billing_ele, differentiated by the start/end dates
You want the description for the record that encompasses the 'p_effective_date' from bil.bill_sum. The kicker is that you can't (or don't want to) include that in the group by. That suggests you've got multiple rows in bil.bill_sum with different effective dates.
The issue is what do you want to happen if you are summarising up those multiple rows with different dates. Which of those dates do you want to use as the one to get the description.
If it doesn't matter, simply use MIN(aa.p_effective_date), or MAX.
Have you looked into the Oracle analytical functions. This is good link Analytical Functions by Example

mysql show rows in order from highest value to lowest value

I have a table that contains a column named views. Each time the user refreshes the page, it updates the view count +1.
What im trying to do, is create a mysql query to output the list of rows based on their views count, from highest to lowest.
this is what i thought would work
SELECT * FROM picdb ORDER BY views DESC LIMIT 10
even when i view it ASCENDING, its all out of whack.
thoughts?
EDIT
the column type is TEXT
SOLVED changed column type to INT and it works fine now. Thanks for pointing it out.
If your column type is TEXT, the default sorting behavior treats the data as strings, and therefore sorts them alphabetically (not numerically).
Change your column type to a number type, and it will sort correctly.
SELECT
*
FROM
tbl
ORDER BY
CAST(views AS UNSIGNED) DESC
LIMIT
10
Might do the trick. The real question is why you have a column containing integers with the text type?
select a,b,CAST(views AS UNSIGNED) c from picdb order by c desc limit 10
This looks like the classic alphanumeric sort problem. If the column type is text, then you are probably seeing order like 1, 10, 15, 20, 3. In other words, it’s sorting by the text value instead of the integer value.
You could change the column to a numeric type, or you could do:
SELECT * FROM picdb ORDER BY CONVERT(views, UNSIGNED INTEGER) DESC LIMIT 10
However, this would not be able to take advantage of any index on the views column. It would be better to change the column to a numeric type if that is indeed what it represents.
If you want to show your table rows from higher value to lower value then use this query.
query = "SELECT * FROM CurrencyTable ORDER BY CAST(currency_rate AS UNSIGNED) DESC";
And if you want to show rows from lower value to higher value then use this query
query-2 = "SELECT * FROM CurrencyTable ORDER BY CAST(currency_rate AS UNSIGNED) ASC";