result based on maximum date with groupBy in laravel - laravel

Here i want to fetch results based on the maximum date from the field so in order to get that i wrote query like this
$latest_reports = Filelist::
select('report_type_id',DB::raw('filename,max(data_date) as latest_date'))
->where('access_id','=',$retailer_supplier_id->id)
->groupBy('report_type_id')
->orderBy('data_date','desc')
->get();
Here is my table please have a look
id access_id filename report_type_id data_date
1 16 filename1 6 2021-02-01
2 16 filename2 6 2021-01-01
3 16 filename3 6 2021-03-01
4 16 filename4 6 2021-04-01
Am getting result like this
id access_id filename report_type_id data_date
4 16 filename1 6 2021-04-01
I want to get result like this
id access_id filename report_type_id data_date
4 16 filename4 6 2021-04-01
Here the first rows filename value is getting..how to solve this

This is a MySQL problem I think. You have specified only one column to group by, but more then one column in the select list so what is presented in those other non-aggregating columns isn't guaranteed to be sensible. Please refer to MySQL Handling of GROUP BY
In SQL I might re-write the query this way:
select * from mytable
where data_date = (select max(data_date) from mytable)
or
select * from mytable
order by data_date
limit 1
depending on my particular needs (and I don't know which is better for you)

UPDATE:
$latest_reports = Filelist::select([
'report_type_id',
'access_id'
DB::raw('MAX(data_date) AS data_date'),
// here can be listed the other fields
])
->where('access_id', $retailer_supplier_id->id)
->groupBy('report_type_id')
->get();
INITIAL:
I had similar working query, just there I had "created_at" timestamp field. Anyway, I think this will work for you:
// assuming, that your table name is "filelist"
$latest_reports = Filelist::select(DB::raw('t.*'))
->from(DB::raw('(SELECT * FROM filelist ORDER BY data_date DESC) t'))
->groupBy('t.report_type_id')
->get();

Related

LPAD Function did not insert zeros from start

I have 3 columns with values like:
projectid disttid cardno
6 3 17422117
I want merge these 3 columns into 1 column like:
projectid disttid cardno new_column
6 3 17422117 00600317422117
I tried with this query but LPAD function did not insert 2 zeros from start
select LPAD(projectid,3,'0')||LPAD(disttid,3,'0')||max(cardno)+1 "NEW_URN"
from we_group_hof_k
where urn like '006%'
group by projectid,disttid;
This query gives this result:
600317422117
Please update the query as shown below and check.Hope this works.
select LPAD(projectid,3,'0')||LPAD(disttid,3,'0')||to_char(max(cardno)+1) "NEW_URN"
from we_group_hof_k
where urn like '006%'
group by projectid,disttid;

Consolidate rows

I'm trying to cut down on rows a report has. There are 2 assets that return on this query but I want them to show up on one row.
Basically if dc.name LIKE '%CT/PT%' then I want it to be same row as the asset. The SP.SVC_PT_ID is the common field to join them.
There will be times when there is no dc.name LIKE '%CT/PT%' however I still want the DV.MFG_SERIAL_NUM to populated just with a Null to the right.
Select SP.SVC_PT_ID, SP.DEVICE_ID, DV.MFG_SERIAL_NUM, dc.name,
substr(dc.name,26)
From EIP.SVC_PT_DEVICE_REL SP,
eip.device_class dc,
EIP.DEVICE DV
Where SP.EFF_START_TIME < To_date('20170930', 'YYYYMMDD') + 1
and SP.EFF_END_TIME is null
and dc.id = DV.device_class_id
and DV.ID = SP.device_id
ORDER BY SP.SVC_PT_ID, DV.MFG_SERIAL_NUM;
I'm not sure I understand what you are saying; test case would certainly help. You said that query you posted returns two rows (only if we saw which ones ...) but you want them to be displayed as the image you attached to the message.
Generally speaking, you can do that using an aggregate function (such as MAX) on certain column(s), along with the GROUP BY clause that contains the rest of them.
Just for example:
select svc_pt_id, max(ctpt_name) ctpt_name, sum(ctpt_multipler) ctpt_multipler
from ...
group by svc_pt_id
As I said: a test case would help people who'd want to answer the question. True - someone might have understood it far better than I did and will provide assistance nevertheless.
EDIT: after you posted sample data (which, by the way, don't match screenshot you posted previously), maybe something like this might do the job: use analytic function to check whether name contains CT/PT; if so, take its data. Otherwise, display both rows.
SQL> with test as (
2 select 14 svc_pt_id, 446733 device_id, 'Generic Electric' name from dual union
3 select 14, 456517, 'Generic CT/PT, Multiplier' from dual
4 ),
5 podaci as
6 (select svc_pt_id, device_id, name,
7 rank() over (partition by svc_pt_id
8 order by case when instr(name, 'CT/PT') > 1 then 1
9 else 2
10 end) rnk
11 from test
12 )
13 select svc_pt_id, device_id, name
14 from podaci
15 where rnk = 1;
SVC_PT_ID DEVICE_ID NAME
---------- ---------- -------------------------
14 456517 Generic CT/PT, Multiplier
SQL>
My TEST table (created by WITH factoring clause) would be the result of your current query.

Select and sum multiple columns for statistic purposes with Laravel query

I have one table scores where I have saving users scores. It's looks like this
table `scores`
id | points | user_id
1 5 1
2 2 1
3 4 1
4 1 3
5 10 2
I want to select each user, sum his points and show as a ranking. The result from above should be
user_id | points
1 11
2 10
3 1
The query with which I came up is
$sumPoints = Scores::select( \DB::raw("sum(points) as numberOfPoints"), \DB::raw("count(id) as numberId"))->groupBy("user_id")->first();
The problem is in ->first() because it's return only one result.. it is working as must. If I try to use ->get() instead I've got Undefined property error. How should I use this?
The query which is working in phpmyadmin
SELECT count(id) as numberId, sum(points) as numberOfPoints FROM `points` GROUP BY `user_id`
You can use something like this
$sumPoints = Scores::select( \DB::raw("sum(points) as numberOfPoints"), \DB::raw("count(id) as numberId"))->groupBy("user_id")->get();
foreach($sumPoints as $point){
dd($point); //OR dd($point->numberOfPoints)
}

Hive - Remove duplicates, keeping newest record - all of it [duplicate]

This question already has answers here:
Retrieve top n in each group of a DataFrame in pyspark
(6 answers)
Closed 6 years ago.
There have been a few questions like this, with no answer, like this one here.
I thought I would post another in hopes of getting one.
I have a hive table with duplicate rows. Consider the following example:
*ID Date value1 value2*
1001 20160101 alpha beta
1001 20160201 delta gamma
1001 20160115 rho omega
1002 20160101 able charlie
1002 20160101 able charlie
When complete, I only want two records. Specifically, these two:
*ID Date value1 value2*
1001 20160201 delta gamma
1002 20160101 able charlie
Why those two? For the ID=1001, I want the latest date and the data that is in that row with it. For the ID=1002, really the same answer, but the two records with that ID are complete duplicates, and I only want one.
So, any suggestions on how to do this? The simple "group by" using the ID and the 'max' date won't work, as that ignores the other columns. I cannot put 'max' on those, as it will pull the max columns from all the records (will pull 'rho' from an older record), which is not good.
I hope my explanation is clear, and I appreciate any insight.
Thank you
Try this:
WITH temp_cte AS (
SELECT mt.ID AS ID
, mt.Date AS Date
, mt.value1 AS value1
, mt.value2 AS value2
, ROW_NUMBER() OVER (PARTITION BY mt.ID ORDER BY mt.Date DESC) AS row_num
FROM my_table mt
)
SELECT tc.ID AS ID
, tc.Date AS Date
, tc.value1 AS value1
, tc.value2 AS value2
FROM temp_cte tc
WHERE tc.row_num = 1
;
Or you can do MAX() and join the table to itself where ID = ID and max_date = Date. HTH.
Edit March 2022:
Since ROW_NUMBER numbers every row and the user only cares about 1 row with the max date there's a better way to do this I discovered.
WITH temp_cte AS (
SELECT mt.ID AS ID
, MAX(NAMED_STRUCT('Date', mt.Date, 'Value1', mt.value1, 'Value2', mt.Value2)) AS my_struct
FROM my_table mt
GROUP BY mt.ID
)
SELECT tt.ID AS ID
, tt.my_struct.Date AS Date
, tt.my_struct.Value1 AS Value1
, tt.my_struct.Value2 AS Value2
FROM temp_cte tt
;

How can I get values from one table to another via similar values?

I have a table called excel that has 3 columns, name, id, and full_name. The name part is the only one I have and I need to fill id and full_name. The other table that contains the data is called tim_pismena and has 2 columns that I need, id and pismeno_name (the actual names are not important, but i'm writing them just for clarity). In pseudooracle code :) the select that gets me the values from the second table would be done something like this:
SELECT tp.id, tp.pismeno_name
FROM tim_pismena tp
WHERE upper(tp.pismeno_name) LIKE IN upper('%(SELECT name FROM excel)%')
and when used with an insert, the end result should be something like
name id full_name
Happy Joe 55 Very fun place Happy Joe, isn't it?
Use merge statement
1 MERGE
2 INTO excel tgt
3 USING tim_pismenae src
4 ON ( upper(src.naziv_pismena) LIKE '%'||upper(tgt.ime)||'%')
5 WHEN MATCHED
6 THEN
7 UPDATE
8 SET tgt.id = src.id
9 , tgt.full_name = src.naziv_pismena
10 WHEN NOT MATCHED
11 THEN
12 INSERT ( tgt.name
13 , tgt.id
14 , tgt.full_name )
15 VALUES ( src.naziv_pismena
16 , src.id
17 , src.naziv_pismena )
18 WHERE (1 <> 1);

Resources