I have a table that stores salary information (SALARY with fields such as NATIONAL_ID, SALYEAR, SALMONTH, SALAMOUNT, DATE_PAID, etc) for employees.
I need to extract data from that table including the last month an employee was paid a salary.
Unfortunately, DATE_PAID column is null for many cases in that table which forces me to think of using a combination of SALYEAR, SALMONTH to determine the highest value.
SALMONTH stores numbers from 1-12 and SALYEAR stores year information i.e 2010, 2015, etc.
Using ROW_NUMBER, we can try:
WITH cte AS (
SELECT t.*, ROW_NUMBER() OVER (PARTITION BY NATIONAL_ID
ORDER BY SALYEAR DESC, SALMONTH DESC) rn
FROM yourTable t
)
SELECT *
FROM cte
WHERE rn = 1;
The above approach will target the latest record for each NATIONAL_ID, with "latest" being defined as having the most recent month in the most recent year.
select max(to_date(sal_year||to_char(sal_month,'FM00'),'yyyymm'))
should do it. The TO_DATE is really just for completeness if you want a date datatype.
You would need to use COALESCE like this:
SELECT MAX(COALESCE(YEAR(DATE_PAID) * 100 + MONTH(DATE_PAID), SALYEAR * 100 + SALMONTH))
FROM tablename
Use Correlated Sub Query -
with temp as (
select national_id,
max(to_number(to_char(salyear)||lpad(to_char(salmonth),2,'0'))) as max_salmonthyear
from salary
group by national_id)
select *
from salary s, temp t
where s.national_id = t.national_id
and to_number(to_char(salyear)||lpad(to_char(salmonth),2,'0')) = t.max_salmonthyear
order by 1;
Why not just use aggregation?
select nationalid, max(salyear * 100 + salmonth) as salyearmonth
from t
group by nationalid;
If you want to convert the yearmonth to a date:
select nationalid,
to_date(max(salyear * 100 + salmonth), 'YYYYMM') as salyearmonth
from t
group by nationalid;
This returns the first date of the salary month.
Related
I have :
SELECT
"Month",
COUNT( Trip_Id ) AS 'Number of Trips'
FROM
Tor_Bikes AS tb
GROUP BY
"Month";
Which gives me a table of each month with its number of trips for that month. I need the month that has the most number of trips. How do I do this?
WARNING: UNTESTED
I'm learning SQL myself, so this is by no means canonical, and there may be mistakes. We all know how to produce such a table:
(SELECT `productID`, count(`productID`) AS `TotalPriceChanges` FROM `ProductCostHistory` GROUP BY `productID`)
ProductID Count(*)
'707' | '3'
'708' | '3'
'709' | '1'
'710' | '1'
'711' | '3'
If I'm understanding correctly, you want to select the Max value of THIS table. Well, you can simply use the above as a derived table - sub query or CTE (Common Table Expression). Using MYSQL it would be something like this:
Select ProductID, max(TotalPriceChanges) FROM
(SELECT `productID`, count(`productID`) AS `TotalPriceChanges` FROM `ProductCostHistory` GROUP BY `productID`) as derivedTable
Group by `ProductID`
We use an alias as to name the derived table, and instead of using the aggregative function count we use the function max. The above works for me.
Final Solution
SELECT Month, Max('Number of Trips') FROM
(
SELECT
"Month",
COUNT( Trip_Id ) AS 'Number of Trips'
FROM
Tor_Bikes AS tb
GROUP BY
"Month" AS DerivedTable;
)
GROUP BY MONTH
You should use subqueries to achieve that:
SELECT MAX(Number_of_Trips) FROM (SELECT "Month", Count( Trip_Id ) FROM
Tor_Bikes AS tb
GROUP BY
"Month";)
Here is the query you are searching for:
SELECT Month, Max('Number of Trips')
FROM
(
SELECT Month, COUNT( Trip_Id ) AS 'Number of Trips'
FROM Trips AS tb
GROUP BY Month
)
Using ORDER BY count() :
SELECT
Month,
count(Trip_Id) AS amount
FROM
Tor_Bikes
GROUP BY
Month
ORDER BY
amount DESC
LIMIT
1
;
I want to check if the salary has been increased or decreased. How can I do that?
A new column can be opened and written as ascending and descending.
I am using SQL Server.
Table:
Use a CTE (or a sub-query) with a LAG() to get each row's preceding wage value.
Then use a CASE expression to categorise the change.
WITH
data_lagged AS
(
SELECT
*,
LAG(wage) OVER (PARTITION BY CurrAccCode ORDER BY StartDate) AS wage_lag
FROM
yourTable
)
SELECT
*,
CASE WHEN wage > wage_lag THEN 'increase'
WHEN wage = wage_lag THEN 'no_change'
WHEN wage < wage_lag THEN 'decrease'
ELSE 'new_wage' END AS wage_change_mode
FROM
data_lagged
I have an oracle DB.
My table has ID and DATE columns (and more).
I would like to select for every ID the next available record after a certain date. For only one ID the query would be:
SELECT * FROM my_table
WHERE id = 1 AND date >= '01.01.2018'
(just ignoring the to_date() function)
How would that look like for multiple IDs? And I do want to SELECT *.
Thanks!
We can use ROW_NUMBER here:
SELECT ID, date -- and maybe other columns
FROM
(
SELECT *,
ROW_NUMBER() OVER (PARTITION BY ID ORDER BY date) rn
FROM my_table
WHERE date >= date '2018-01-01'
) t
WHERE rn = 1
The idea here is to assign a row number to each ID partition, starting with the earliest date which occurs after the cutoff you specify. The first record from each partition would then be the immediate next date, assuming it exists.
I have a select query that gets a CarID, month, mileage and CO2 emission.
Now it gives for each month per car the mileage like this:
month 1: 5000
month 2: 5200
...
What I really need is that it takes the current value minus the previous one. I get data between a certain time frame and I already included a mileage point before that time frame. So it would be possible to get the total miles per month, I just don't know how. What I want is this.
pre timeframe: 5000
month 1: 200
month 2: 150
...
How would I do this?
edit: code, I have not yet tried anything as I have no clue how to start to do this.
resultlist as (
SELECT
CarID
, '01/01/2000' as beginmonth
, MAX(kilometerstand) as Kilometers
, MAX(Co2Emission) as CO2
FROM
totalmileagelist
GROUP BY CarID
UNION
SELECT
CarID
, beginmonth
, MAX(kilometerstand) as Kilometers
, MAX(Co2Emission) as CO2
FROM
resultunionlist
GROUP BY CarID, beginmonth
)
select * from resultlist
order by CarID, beginmonth
Edit2: explanation to the code
In the first part of the result list I grab the latest mileage per car. In the second part, after the union, I grab per month per car the latest mileage.
If you just want to subtract the previous milage, use the lag() function:
select ml.*,
(kilometerstand - lag(kilometerstand) over (partition by carid order by month)
) as diff
from totalmileagelist ml;
lag() is available in SQL Server 2012+. In earlier versions you can use a correlated subquery or outer apply.
(I missed the version because it is in the title and not on a tag.) In SQL Server 2008:
select ml.*,
(ml.mileage - mlprev.mileage) as diff
from totalmileagelist ml outer apply
(select top 1 ml2.*
from totalmileagelist ml2
where ml2.CarId = ml.CarId and
ml2.month < ml.month
order by ml2.month desc
) mlprev;
Try like this:
SELECT id, yourColumnValue,
COALESCE(
(
SELECT TOP 1 yourColumnValue
FROM table_name t
WHERE t.id> tbl.id
ORDER BY
rowInt
), 0) - yourColumnValue AS diff
FROM table_name tbl
ORDER BY
id
or like this using rank()
select rank() OVER (ORDER BY id) as 'RowId', mileage into temptable
from totalmileagelist
select t1.mileage - t2.mileage from temptable t1, temptable t2
where t1.RowId = t2.RowId - 1
drop table temptable
You have three fields ID, Date and Total. Your table contains multiple rows for the same day which is valid data however for reporting purpose you need to show only one row per day. The row with the highest ID per day should be returned the rest should be hidden from users (not returned).
To better picture the question below is sample data and sample output:
ID, Date, Total
1, 2011-12-22, 50
2, 2011-12-22, 150
The correct result is:
2, 2012-12-22, 150
The correct output is single row for 2011-12-22 date and this row was chosen because it has the highest ID (2>1)
Assuming that you have a database that supports window functions, and that the date column is indeed just date (and not datetime), then something like:
SELECT
* --TODO - Pick columns
FROM
(
SELECT ID,[Date],Total,ROW_NUMBER() OVER (PARTITION BY [Date] ORDER BY ID desc) rn
FROM [Table]
) t
WHERE
rn = 1
Should produce one row per day - and the selected row for any given day is that with the highest ID value.
SELECT *
FROM table
WHERE ID IN ( SELECT MAX(ID)
FROM table
GROUP BY Date )
This will work.
SELECT *
FROM tableName a
INNER JOIN
(
SELECT `DATE`, MAX(ID) maxID
FROM tableName
GROUP BY `DATE`
) b ON a.id = b.MaxID AND
a.`date` = b.`date`
SQLFiddle Demo
Probably
SELECT * FROM your_table ORDER BY ID DESC LIMIT 1
Select MAX(ID),Data,Total from foo
for MySQL
Another simple way is
SELECT TOP 1 * FROM YourTable ORDER BY ID DESC
And, I think this is the most simple way!
SELECT * FROM TABLE_SUM S WHERE S.ID =
(
SELECT MAX(ID) FROM TABLE_SUM
WHERE CDATE = GG.CDATE
GROUP BY CDATE
)