I am using laravel 5, and I have a question for the SQL
there is the table that record the function change of employee.
I just need the latest function so I wonder to use the "group by".
but even I get the latest date, I could not get the corresponding data .
The most close to what I want is like this
DB::table('function_history')
->select(DB::raw('id_history,function_history.CUID,
max(function_change_date)as time, id_function'))
->orderBy('time','desc') ->groupBy('CUID')->get();
Thanks for your help
Ok. You just need to know the rows that corresponds to rows with max date.
Pure sql query:
select
id_history, CUID, id_function, function_change_date
from
function_history t1
join
(select max(function_change_date) as maxdt from function_history group by CUID) t2 on t1.function_change_date = t2.maxdt
Laravel query:
DB::table('function_history')->select('id_history', 'CUID', 'id_function', 'function_change_date')
->join(DB::raw('(select max(function_change_date) as maxdt from function_history group by CUID) temp'),
'temp.maxdt', '=', 'date'
)->get();
You can select all employees with their current function with this SQL query:
SELECT
function_history.*
FROM
function_history,
(
SELECT
MAX(function_change_date) as last_change_date,
CUID
FROM
function_history
GROUP BY
CUID
ORDER BY function_change_date DESC
) tmp
WHERE
function_history.CUID = tmp.CUID
AND
function_history.function_change_date = tmp.last_change_date
I’m not sure why you’re building a raw SQL query, and grouping. If you just want the latest function changes for a particular CUID, then select data and order by the date:
DB::table('function_history')
->where('CUID', '=', $cuid)
->orderBy('function_change_date')
->get();
Please use below query and convert into laravel format
SELECT
`CUID`,
MAX(`function_change_date`) AS timechange,
(SELECT
`id_function`
FROM
`function_history` fc
WHERE fc.function_change_date = MAX(f.`function_change_date`)) AS id_function
FROM
`function_history` f
GROUP BY CUID ;
Related
I want a query that returns a record set of the shaded rows from the table above for each unique case_id by the latest data_level_assinged value. I tried something like this:
SELECT case_id, level, date_level_assigned
FROM table
SORT BY case_id, date_level_assigned DESC;
From reading it looks like I need to use an aggregate function like MAX(data_level_assinged) but am not sure how to do this.
You're almost there.
Using MAX is a good approach.
SELECT b.case_id, a.level, b.date_level_assigned FROM tablename a
JOIN
( SELECT MAX(date_level_assigned) as date_level_assigned, case_id
FROM tablename
GROUP BY case_id
) as b
ON a.case_id = b.case_id AND a.date_level_assigned = b.date_level_assigned
You can do it in this way
I've got some data that has a DeviceID column, a scan time column and some other columns.
For each of the deviceIDs, I want to return only the most recent row based on the scan time.
I am trying to create this query so that I can use it as a view and report on the data.
The database is a Microsoft SQL Server database and I'm running the query from SQL Server 2014 Management Studio.
The closest I've gotten to getting this to work is this :
SELECT
DeviceID,
AVSolutionName,
DefinitionsUpToDate,
ScanningEnabled,
Expired,
ScanTime
FROM
dbo.fact_AVSecurity
WHERE
(ScanTime IN (SELECT DISTINCT MAX(ScanTime) AS LastScan
FROM dbo.fact_AVSecurity AS Avs
GROUP BY DeviceID))
Unfortunately this is returning multiple values for the same ID.
ScanTime ScanningEnabled Expired DeviceID DefinitionsUpToDate AVSolutionName
10/12/2018 10:13 TRUE FALSE 15994 TRUE Webroot SecureAnywhere
4/12/2018 14:30 TRUE TRUE 15994 TRUE Webroot SecureAnywhere
What I'd like returned is just that first most recent row:
ScanTime ScanningEnabled Expired DeviceID DefinitionsUpToDate AVSolutionName
10/12/2018 10:13 TRUE FALSE 15994 TRUE Webroot SecureAnywhere
I've tried different approaches like :
SQL - Returning only the most recent row
But can't seem to get them working. I'm not sure if it's something I'm doing wrong or if the specific brand of SQL I'm using doesn't do the "top 1" thing.
Is there a way to do what I'm after? How close am I with what I have?
use a window function with a CTE?
With CTE AS (
SELECT t.DeviceID
, t.AVSolutionName
, t.DefinitionsUpToDate
, t.ScanningEnabled
, t.Expired
, t.ScanTime
, Row_Number() over (partition by DeviceID order by scanTime Desc) RN
FROM dbo.fact_AVSecurity t)
SELECT *
FROM CTE
WHERE RN=1
You are close to the solution. You just need a few changes in your correlated subquery :
add a WHERE condition in your subquery that limits the search to the current DeviceID
No need to use an IN clause to match the subquery, equality should be fine as only one record is expected anyway
No need to use DISTINCT as you are already using a GROUP BY
Query :
SELECT
t.DeviceID,
t.AVSolutionName,
t.DefinitionsUpToDate,
t.ScanningEnabled,
t.Expired,
t.ScanTime
FROM dbo.fact_AVSecurity AS t
WHERE t.ScanTime =
(SELECT MAX(ScanTime) AS LastScan
FROM dbo.fact_AVSecurity AS Avs
WHERE deviceID = t.deviceID
GROUP BY DeviceID
)
Check this:
SELECT t.DeviceID, t.AVSolutionName, t.DefinitionsUpToDate, t.ScanningEnabled, t.Expired, t.ScanTime
FROM dbo.fact_AVSecurity AS t
WHERE t.ScanTime = (SELECT MAX(Avs.ScanTime) FROM dbo.fact_AVSecurity AS Avs WHERE Avs.DeviceID = t.DeviceID)
for each DeviceID fetches the row that has ScanTime = MAX(ScanTime)
If you have an auto-increment column on your table (you generally should have one on every table), use that instead of timestamps, since SQL Server DateTime type only has a resolution of 1/300th of a second and should not be assumed to be a unique timestamp.
SELECT X.LastEntryID, DeviceID = Y.ID, ...
FROM
(
SELECT LastEntryID = MAX(ID)--latest entry for the device
FROM dbo.fact_AVSecurity
GROUP BY DeviceID--you don't even need to return DeviceID since ID is auto-increment and thus unique in the table
) AS X
INNER JOIN dbo.fact_AVSecurity AS Y ON
Y.ID = X.LastEntryID
This presumes you don't backdate your data or populate using IDENTITY_INSERT
Just one final option because I didn't see it mentioned
You can use the WITH TIES in concert with Row_Number()
That said, xQbert's solution (+1) would be more performant, especially with larger tables
Example
SELECT Top 1 with ties *
FROM dbo.fact_AVSecurity
Order By Row_Number() over (partition by DeviceID order by scanTime Desc)
I have a table consisting of a date column
I need to select this column additionally I need select the prev date that does not reside in db
if it exists or current data
I tried the following query
select hst1.QUERYID,hst1.starttime,
ZEROIFNULL(hst2.starttime) as delta
from dbqlogtbl_dba_hst hst1
left outer join dbqlogtbl_dba_hst hst2 on
hst1.QUERYID = hst2.QUERYID;
I am getting errors fetching results
You seem to just want lag():
select hst1.QUERYID, hst1.starttime,
lag(hst1.starttime) over (order by hst1.starttime)
from dbqlogtbl_dba_hst hst1 left join
dbqlogtbl_dba_hst hst2
on hst1.QUERYID = hst2.QUERYID ;
I am guessing that you really want this per queryid, so you would then need partition by:
lag(hst1.starttime) over (partition by hst1.QUERYID order by hst1.starttime)
I'm trying to count track_uri that are associated to a given playlist_uri in a day in a one month window and have composed the following sql:
SELECT
playlist_uri, playlist_date, track_uri, count(track_uri)
over (partition by playlist_uri, playlist_date) as count_tracks
FROM
tbl1
WHERE
_PARTITIONTIME BETWEEN '2017-09-09' AND '2017-10-09'
AND playlist_uri in (
SELECT playlist_uri from tbl2 WHERE playlist_owner = "spotify"
)
However I am getting the following output:
I instead would like it to show me the count of track_uri for each playlist_uri on each day.
Would really appreciate some help with this.
Not sure if I understand your question correctly, but if you might not need to use the window function for that:
SELECT
playlist_uri, playlist_date, COUNT(DISTINCT track_uri)
FROM
tbl1
WHERE
_PARTITIONTIME BETWEEN '2017-09-09' AND '2017-10-09'
AND playlist_uri in (
SELECT playlist_uri from tbl2 WHERE playlist_owner = "spotify"
)
GROUP BY 1, 2;
i have table as shown here in this picture --> http://www.directupload.net/file/d/3710/lj7etq5j_png.htm
I need the correct Query to get only data_id 10.
The query should be like this: Compare the latest date rows (2014-08-08) with the earliest date rows (2014-08-06). If there is a row on 2014-08-08 which is NOT at 2014-08-06, this row should returned.
I already tried it with self-joins and Sub-Selects, but i did't get it work.
Thx for any help!
Maybe something like this is what you're looking for?
select * from Table1
where
data not in (
select data from Table1
where dataOfDate = (select min(dataofdate) from Table1)
)
and dataOfDate = (select max(dataofdate) from Table1)
The first where clause compares the data field of the returned rows to the data field in the set of oldest rows and the second where clause limits the set of rows the the newest.
Note that I'm only comparing rows based on thedatafield, so you might have to change the query if you want to includenextTableIdin the comparison.
Here is a sample SQL Fiddle.
How about something like this:
SELECT d1.* FROM Dates d1 LEFT JOIN Dates d2 ON d1.nextTableId = d2.nextTableId WHERE d1.dataofDate = '2014-08-08' AND d2.dataofDate = '2014-08-06' AND d2.data_id IS NULL;
SELECT `data_id`
FROM `my_table`
WHERE `dataOfDate` = (SELECT MAX(`dataOfDate`) FROM `my_table`)
AND `nextTableId` NOT IN (
SELECT `nextTableId` FROM `my_table` WHERE `dataOfDate` = (SELECT MIN(`dataOfDate`) FROM `my_table`)
)
select all rows with max date
that don't have values amongst rows with min date
edit ops, too late