We are working on a project for school and have a small issue with a query.
What we try to do is the following:
Select the education-unit(s) with the same version_vid and after that select the education-unit with the latest version_date.
But whatever we try, the education-unit with the lowest euid is returning.
We are using the Yii2 framework for this project, the ActiveQuery we use is:
EducationUnit::find()->groupBy('version_vid')->orderBy('version_date DESC');
SQL Fiddle:
http://sqlfiddle.com/#!9/9929d/2/0
Thanks in advance!
Maybe this can help you:
EducationUnit::find()
->from('select * from education_unit ORDER BY version_date DESC')
->groupBy('version_vid')
->all();
Wrap a select around your query, after that do the group by:
SELECT * FROM
( SELECT * FROM `education_unit` ORDER BY `version_date` DESC ) a
GROUP BY a.`version_vid`
Why it didn't work in your query is because SQL has an execution plan as below:
FROM clause
WHERE clause
GROUP BY clause
HAVING clause
SELECT clause
ORDER BY clause
The reason you are getting the lowesteuid is that the ORDER BY is applied after the GROUP BY and the GROUP BY is choosing arbitrary values from the group to return.
This is a classic top in group question and has been answered previously
I personally like the answer supplied by Bill Karwin which when applied to your situation becomes:
SELECT t.*
FROM table t
LEFT JOIN table t2
ON t2.version_vid = t.version_vid
AND t2.version_date > t.version_date
WHERE t2.version_vid IS NULL
Another common solution is:
SELECT t.*
FROM table t
JOIN (
SELECT version_id, MAX(version_date) version_date
FROM table
GROUP BY version_id
) t2
ON t2.version_id = t1.version_id
AND t2.version_date = t1.version_date
Related
i need to create query with group by and order by, and i dont know how to do it.
query should return one record for the newest date for existing device_serial_number. enter image description here
so i would to get id 591 nad 592
solution can be in sql or the best way it will be in symfony, through query builder etc.
There are many ways to accomplish what you want.
First Way
The oldest way to select first, best, worst, whatever within a group is with a correlated subquery:
Select * from mytable outer
Where created_at = (
Select max(created_at)
from mytable inner
Where inner.device_serial_number = outer.device_serial_number
)
Second Way
Use a subselect to find earliest dates for all devices, them join back to the original table to filter:
Select a.*
From mytable a Inner Join
(Select device_serial_number, max(created_at) as latedate
From mytable b
Group By device_serial_number
) b
On a.device_serial_number=b.device_serial_number
And a.created_at=b.latedate
Third way
Use a window function to rank order all the dates and then pick the number one ranking.
Select * From (
Select *
, rank() Over (Partition By device_serial_number Order by created_at desc) as myrank
From mytable
)
Where myrank=1
Notice that while these 3 solutions use different aspects of SQL, they all have a common analytical approach. They are all two step processes whose first (inner) part involves finding the most recent created_at date for each device_serial_number and then reapplying that result back to the original table in the second (outer) part.
I want to ask how sql join uses limits on one table
I have searched Google but the query I did was different and that made me confused
$queryAnime = "SELECT *
FROM `anime`
JOIN `episode` ON `anime`.`link` = `episode`.`idanime`
ORDER BY `anime`.`id` DESC
";
$anime = $this->db->query($queryAnime)->result_array();
when I add a limit in the normal way only 1 array appears
I let 'anime' appear all and 'episodes' only show one array
and sorry my English is bad I hope you understand and dabat helps me
If I understand your question correctly, you need to specify the columns you need in the Select statements and not use *, and use a Select Distinct
So for example
SELECT DISTINCT `show_name`,`eposode`
FROM `anime` JOIN `episode`
ON `anime`.`link` = `episode`.`idanime`
ORDER BY `anime`.`id` DESC
I have a simple question.
I have to join multiple queries and most of them has ad IN clausole.
Unfortunally, MySQL doesn't allow ORDER BY in an UNION (only outside all unions) but I need a specific ordering that I can't get with an outside order by.
Question is:
If I have a IN clausole like
foo in ('newyork','boston','atlanta')
may I assume MySql's engine will order the resulting rows by IN position (so, first all the row with foo = 'newyork' then 'boston' etc...
Thanks.
No. It's nothing like that. You need to explicitly add an order by clause.
If you want to order your rows based on position in a set, you can use field function.
order by field(foo,'newyork','boston','atlanta')
Select *
from
(
Select * from Temp1
order by x
) Tbl1
UNION
Select *
from
(
Select * from Temp2
order by y
) Tbl2
Try this.
I am trying to use a select query within another select query in the from clause.This is a mysql query.
SELECT invoiceNo, SUM(weight), COUNT(barcode), sum_total
FROM (SELECT * FROM `selected_items` WHERE date LIKE '07-Jan-2016' ORDER BY id DESC)
WHERE date LIKE '07-Jan-2016' GROUP BY invoiceNo;
This is how my database looks like.
How can I achieve something like this where I have a table which I order by id desc and use another select query on the result of this query.The above query gives me an error #1248 - Every derived table must have its own alias.Can anyone help I am new to programming.
I hope this will help you out .
SELECT invoiceNo, SUM( weight ) , COUNT( barcode ) , sum_total
FROM (SELECT * FROM `selected_items`
WHERE DATE LIKE '07-Jan-2016'
ORDER BY id DESC
)a
GROUP BY invoiceNo;
I didn't get it why you are using sub-query. You can directly use the table 'selected_items' and check the condition in where clause.Like:
SELECT invoiceNo, SUM(weight), COUNT(barcode)
from 'selected_items'
WHERE date LIKE '07-Jan-2016'
GROUP BY invoiceNo
Order By Id
You dont need to do order by inside inner select query. And in MySQL, you need to give an alias to a derived table, a in this example.
SELECT invoiceNo, SUM(weight), COUNT(barcode), sum_total
FROM
(
SELECT * FROM `selected_items` WHERE date LIKE '07-Jan-2016'
) a
WHERE date LIKE '07-Jan-2016' GROUP BY invoiceNo;
Without looking at data, it is difficult to decide to order by but this query will work for you.
You're query is almost right. However there's only missing. You must used an ALIAS.
SELECT * FROM
(
SELECT * FROM #table
)AS tbl1 WHERE field1 = 'test'
I have two tables;
I'm trying to produce a statement (like a bank statement) to show all charges and all payments. The charges and payments need to be displayed in date order based on the statement_date field.
I'm pretty sure I need to use 'unions' but I just can't seem to find a solution.
My effort so far is;
$statement_sql = "(SELECT * FROM accounts_tenant_charge)
UNION
(SELECT * FROM accounts_tenant_payment)
ORDER BY statement_date";
Thanks in advance.
Thanks for your help. The following query worked for me;
SELECT tenant_charge_date as statement_date, tenant_charge_id as reference, tenant_charge_total_amount as debit, NULL as credit, 'Charge' as type FROM accounts_tenant_charge
UNION ALL
SELECT tenant_payment_date as statement_date, tenant_payment_id as reference, NULL as debit, tenant_payment_amount as credit, 'Payment' as type FROM accounts_tenant_payment
ORDER BY statement_date
You must be make nested query. Firstly, you make union query based on your tables and put in inside query. Then, you make SELECT query and put in outside. Don't forget to give alias table for outside query.
You can try this code :
SELECT * FROM
(
(SELECT * FROM accounts_tenant_charge)
UNION
(SELECT * FROM accounts_tenant_payment)
) a
ORDER BY a.statement_date ASC
Your tables have different number of columns, therefore you cant union them right away by doing a select * . You have to select an equal number of columns from both tables. Like:
select
tenant_charge_id as `id`,
tenant_charge_date as `date`,
tenant_charge_total_amonunt as `amount`
union
select
tenant_payment_id,
tenant_payment_date,
tenant_payment_amount
order by
`date` asc