I have a table and it's data looks like this:
id name date
--------- --------- ----------
1 a 2012-08-30 10:36:27.393
1 b 2012-08-30 14:36:27.393
2 c 2012-08-30 13:36:27.393
2 d 2012-08-30 16:36:27.393
I retrieve the max date time with this query:
select
t1.id
,t1.name
,t1.date
from
table1 t1
inner join (
SELECT id,Max(date) as mymaxdate
FROM table1
group by id
) mt1
on t1.id = mt1.id
and t1.date = mt1.mymaxdate
result:
1 b 2012-08-30 14:36:27.393
2 d 2012-08-30 16:36:27.393
how can write this query in entity?
Thanks
The tricky part is that you also want the name of the item having the max date, otherwise the grouping would be much simpler. But it is possible by an almost 1:1 reproduction of the sql query:
from t in table1
join m in
(from t in table1
group t by t.id into g
select new { g.Key, mymaxdate = g.Max (x => x.date) })
on new { t.id, t.date } equals new { id = m.Key, date = m.mymaxdate }
select t
A join on multiple fields is done by creating anonymous types (new {t.id, t.date} and new {id = m.Key, date = m.mymaxdate}) where the names and types of the properties (id and date) should match.
Related
I have table with self-related foreign keys and can not get how I can receive firs child or descendant which meet condition. My_table structure is:
id
parent_id
type
1
null
union
2
1
group
3
2
group
4
3
depart
5
1
depart
6
5
unit
7
1
unit
I should for id 1 (union) receive all direct child or first descendant, excluding all groups between first descendant and union. So in this example as result I should receive:
id
type
4
depart
5
depart
7
unit
id 4 because it's connected to union through group with id 3 and group with id 2 and id 5 because it's connected directly to union.
I've tried to write recursive query with condition for recursive part: when parent_id = 1 or parent_type = 'depart' but it doesn't lead to expected result
with recursive cte AS (
select b.id, p.type_id
from my_table b
join my_table p on p.id = b.parent_id
where b.id = 1
union
select c.id, cte.type_id
from my_table c
join cte on cte.id = c.parent_id
where c.parent_id = 1 or cte.type_id = 'group'
)
Here's my interpretation:
if type='group', then id and parent_id are considered in the same group
id#1 and id#2 are in the same group, they're equals
id#2 and id#3 are in the same group, they're equals
id#1, id#2 and id#3 are in the same group
If the above is correct, you want to get all the first descendent of id#1's group. The way to do that:
Get all the ids in the same group with id#1
Get all the first descendants of the above group (type not in ('union', 'group'))
with recursive cte_group as (
select 1 as id
union all
select m.id
from my_table m
join cte_group g
on m.parent_id = g.id
and m.type = 'group')
select mt.id,
mt.type
from my_table mt
join cte_group cg
on mt.parent_id = cg.id
and mt.type not in ('union','group');
Result:
id|type |
--+------+
4|depart|
5|depart|
7|unit |
Sounds like you want to start with the row of id 1, then get its children, and continue recursively on rows of type group. To do that, use
WITH RECURSIVE tree AS (
SELECT b.id, b.type, TRUE AS skip
FROM my_table b
WHERE id = 1
UNION ALL
SELECT c.id, c.type, (c.type = 'group') AS skip
FROM my_table c
JOIN tree p ON c.parent_id = p.id AND p.skip
)
SELECT id, type
FROM tree
WHERE NOT skip
I have a query which returns next table with name first_table:
Name
ID
First
1
Second
2
And I need to join another table named second_table:
ID
ParentID
22
1
33
323
By the columns first_table."ID" = second_table."ParentID", so if first_table_id exists, I need to add one more row with its first_table."Name" value
So the result should be:
Name
ID
First
1
First
22
Second
2
You can do something like this (result here)
select t1.name,t1.id
from t1 join t2 on t1.id = t2.parent_id
union
select t1.name,t2.id
from t1 join t2 on t1.id = t2.parent_id
union
select t1.name,t1.id
from t1
where t1.id not in (select parent_id from t2)
order by name,id
For an example, I would like to select id with max date group by category, the result is: 7, 2, 6
id category date
1 a 2013-01-01
2 b 2013-01-03
3 c 2013-01-02
4 a 2013-01-02
5 b 2013-01-02
6 c 2013-01-03
7 a 2013-01-03
8 b 2013-01-01
9 c 2013-01-01
This is the SQL I think can work:
SELECT * FROM Table1 t1
JOIN
(
SELECT category, MAX(date) AS MAXDATE
FROM Table1
GROUP BY category
) t2
ON T1.category = t2.category
AND t1.date = t2.MAXDATE
But how to translate that into a query on Ecto?
You can use subquery function
subquery = from t in "Table1"
|> select([t], %{categoty: t.category, max_date: max(t.date)})
|> group_by([t], t.category)
from t in "Table1"
|> join(:inner, [u], t in subquery(subquery), t.category == u.category and t.max_date == u.date)
|> Repo.all
An issue with many frameworks is that they cannot capture all the complexities of a SQL SELECT statement. The easiest solution: wrap your complex query in a view:
CREATE VIEW my_complex_view AS
SELECT * FROM Table1 t1
JOIN (
SELECT category, MAX(date) AS maxdate
FROM Table1
GROUP BY category) t2
ON t1.category = t2.category AND t1.date = t2.maxdate;
Now you have a simple query (SELECT * FROM my_complex_view) which any decent framework can easily handle.
I have a table and it's data looks like this:
id name date
--------- --------- ----------
1 a 2012-08-30 10:36:27.393
1 b 2012-08-30 14:36:27.393
2 c 2012-08-30 13:36:27.393
2 d 2012-08-30 16:36:27.393
I retrieve the max datetime with this query:
SELECT id,Max(date) as mymaxdate
FROM table1
group by id
This query givse me two rows like this:
1 2012-08-30 14:36:27.393
2 2012-08-30 16:36:27.393
It's correct, but how can i change it to retrieve this result?
1 b 2012-08-30 14:36:27.393
2 d 2012-08-30 16:36:27.393
Thanks
For SQL Server 2005+
WITH cteMaxDate AS (
SELECT id, name, date,
ROW_NUMBER() OVER(PARTITION BY id ORDER BY date DESC) AS RowNum
FROM table1
)
SELECT id, name, date
FROM cteMaxDate
WHERE RowNum = 1;
One of the options:
select
t1.id
,t1.name
,t1.date
from
table1 t1
inner join (
SELECT id,Max(date) as mymaxdate
FROM table1
group by id
) mt1
on t1.id = mt1.id
and t1.date = mt1.mymaxdate
My table is like
ID FName LName Date(mm/dd/yy) Sequence Value
101 A B 1/10/2010 1 10
101 A B 1/10/2010 2 20
101 X Y 1/2/2010 1 15
101 Z X 1/3/2010 5 10
102 A B 1/10/2010 2 10
102 X Y 1/2/2010 1 15
102 Z X 1/3/2010 5 10
I need a query that should return 2 records
101 A B 1/10/2010 2 20
102 A B 1/10/2010 2 10
that is max of date and max of sequence group by id.
Could anyone assist on this.
-----------------------
-- get me my rows...
-----------------------
select * from myTable t
-----------------------
-- limiting them...
-----------------------
inner join
----------------------------------
-- ...by joining to a subselection
----------------------------------
(select m.id, m.date, max(m.sequence) as max_seq from myTable m inner join
----------------------------------------------------
-- first group on id and date to get max-date-per-id
----------------------------------------------------
(select id, max(date) as date from myTable group by id) y
on m.id = y.id and m.date = y.date
group by id) x
on t.id = x.id
and t.sequence = x.max_seq
Would be a simple solution, which does not take account of ties, nor of rows where sequence is NULL.
EDIT: I've added an extra group to first select max-date-per-id, and then join on this to get max-sequence-per-max-date-per-id before joining to the main table to get all columns.
I have considered your table name as employee..
check the below thing helped you.
select * from employee emp1
join (select Id, max(Date) as dat, max(sequence) as seq from employee group by id) emp2
on emp1.id = emp2.id and emp1.sequence = emp2.seq and emp1.date = emp2.dat
I'm a fan of using the WITH clause in SELECT statements to organize the different steps. I find that it makes the code easier to read.
WITH max_date(max_date)
AS (
SELECT MAX(Date)
FROM my_table
),
max_seq(max_seq)
AS (
SELECT MAX(Sequence)
FROM my_table
WHERE Date = (SELECT md.max_date FROM max_date md)
)
SELECT *
FROM my_table
WHERE Date = (SELECT md.max_date FROM max_date md)
AND Sequence = (SELECT ms.max_seq FROM max_seq ms);
You should be able to optimize this further as needed.