SQL group by and max and other fields - sql

I have a table that contains:
ITEMID COSTAMOUNTPOSTED QTY DATEPHYSICAL
10001 20 20 2014-10-01
10001 30 20 2014-10-20
10005 20 20 2014-10-01
10005 20 30 2014-10-15
I want to select the last physical action with the item, the result I want to get is:
ITEMID COSTAMOUNTPOSTED QTY DATEPHYSICAL
10001 30 20 2014-10-20
10005 20 30 2014-10-15
The query I run :
SELECT itemid,costamountposted,qty,datephysical
FROM A
where datephysical =(select max(datephysical)
FROM A
But I only get result with items that have biggest physical date. Any suggestions?

You can do this using subquery,
SELECT a.*
FROM tableName a
INNER JOIN
(
SELECT ITEMID , MAX(DATEPHYSICAL) max_date
FROM tableName
GROUP BY ITEMID
) b ON a.ITEMID = b.ITEMID AND a.DATEPHYSICAL = b.max_date

Related

How to get latest records based on two columns of max

I have a table called Inventory with the below columns
item warehouse date sequence number value
111 100 2019-09-25 12:29:41.000 1 10
111 100 2019-09-26 12:29:41.000 1 20
222 200 2019-09-21 16:07:10.000 1 5
222 200 2019-09-21 16:07:10.000 2 10
333 300 2020-01-19 12:05:23.000 1 4
333 300 2020-01-20 12:05:23.000 1 5
Expected Output:
item warehouse date sequence number value
111 100 2019-09-26 12:29:41.000 1 20
222 200 2019-09-21 16:07:10.000 2 10
333 300 2020-01-20 12:05:23.000 1 5
Based on item and warehouse, i need to pick latest date and latest sequence number of value.
I tried with below code
select item,warehouse,sequencenumber,sum(value),max(date) as date1
from Inventory t1
where
t1.date IN (select max(date) from Inventory t2
where t1.warehouse=t2.warehouse
and t1.item = t2.item
group by t2.item,t2.warehouse)
group by t1.item,t1.warehouse,t1.sequencenumber
Its working for latest date but not for latest sequence number.
Can you please suggest how to write a query to get my expected output.
You can use row_number() for this:
select *
from (
select
t.*,
row_number() over(
partition by item, warehouse
order by date desc, sequence_number desc, value desc
) rn
from mytable t
) t
where rn = 1

Find Max Value and date between date range returning mutliplie records

I hope someone can help me, I been working on this all day.
I need to get max value, and the date and id where that max value is associated with between specific date ranges.
Here is my code , and I have tried many different version but it still returning more than one ID and date
SELECT distinct bw_s.id, avs.carProd, cd_s.RecordDate,
cd_s.milkProduction as MilkProd,
cd_s.WaterProduction as WaterProd
FROM tblTest bw_s
INNER JOIN tblTestCp cd_s WITH(NOLOCK)
ON bw_s.id=cd_s.id
AND cd_s.recorddate BETWEEN '08/06/2014' AND '10/05/2014'
Inner Join
( select id, max(CarVol) as carProd
from tblTestCp
where recorddate BETWEEN '08/06/2014' AND '10/05/2014'
group by id ) avs
on avs.id = bw_s.id
order by id
I have table like this
id RecordDate carProd MilkProd WaterProd
47790 2014-10-05 132155 0 225
47790 2014-10-01 13444 0 0
47790 2014-08-06 132111 10 100
47790 2014-09-05 10000 500 145
47790 2014-09-20 10000 800 500
47791 2014-09-20 10000 300 500
47791 2014-09-21 10001 400 500
47791 2014-08-21 20001 600 500
And the result should be ( max carprod)
id RecordDate carProd MilkProd WaterProd
47790 2014-10-05 132155 0 225
47791 2014-08-21 20001 600 500
I've assumed that the name of your table is "Data":
SELECT
*
FROM
Data
WHERE
Data.RecordDate BETWEEN '2014-08-21' AND '2014-10-01'
ORDER BY
Data.carProd DESC
LIMIT 1;
Make sure to change the dates to match what your particular requirements are.

SQL Select latest row by date

I have a large amount of data that updates every 10 minutes or so.
There are 128 unique ID's that need to be returned but with only there latest values
CURRENT CODE
SELECT DISTINCT
id,
MAX(extractdate) AS [extractdate],
total,
used,
free
FROM
maintable
INNER JOIN datatable ON maintable.unkey = datatable.dataunkey
GROUP BY id, total, used, free
ORDER BY id
CURRENT OUTPUT
id extractdate total used free
1 2014-08-28 00:20:00.000 50 20 30
1 2014-08-28 00:30:00.000 50 30 20
1 2014-08-28 00:40:00.000 50 10 40
2 2014-08-28 00:20:00.000 50 20 30
2 2014-08-28 00:30:00.000 50 30 20
2 2014-08-28 00:40:00.000 50 25 25
etc etc
**DESIRED OUTPUT**
id extractdate total used free
1 2014-08-28 00:40:00.000 50 10 40
2 2014-08-28 00:40:00.000 50 25 25
etc etc
Try:
SELECT
a.id,
a.extractdate,
a.total,
a.used,
a.free
FROM(
SELECT
id,
MAX(extractdate) AS [extractdate],
total,
used,
free,
ROW_NUMBER()OVER(partition by id ORDER BY MAX(extractdate) desc) AS rnk
FROM maintable
INNER JOIN datatable ON maintable.unkey = datatable.dataunkey
GROUP BY id, total, used, free )a
WHERE a.rnk = 1
Should work, i've just tested it on the similar fall, only without join:
SELECT id, extractdate,total,used,free
FROM maintable m INNER JOIN datatable ON m.unkey = datatable.dataunkey
where extractdate = (select max(extractdate) from manitable m1 where m1.id = m.id)
ORDER BY id

Split a Table into 2 or more Tables based on Column value

I have a Table called "MIVTable" which has the following records,
MIVID Quantity Value
------ ---------- --------
14 10 3000
14 20 3500
14 15 2000
15 20 3000
15 50 7500
16 25 2000
Here, I need to store the above Table into two tables such as "HeaderTbl" and "DetailTbl" based on the MIVID as follows:
HeaderTbl:
HID MIVID TotalQuantity TotalValue
----- ------- ------------- -----------
1 14 45 8500
2 15 70 10500
3 16 25 2000
Here HID is the Primary Key with Identity Column.
DetailTbl:
HID MIVID Quantity Value
----- ------- ------------ -------
1 14 10 3000
1 14 20 3500
1 14 15 2000
2 15 20 3000
2 15 50 7500
3 16 25 2000
Suppose, if the MIVTable contains 4 different MIVID means, then 4 row should be created based on the MIVID on the HeaderTbl. How to do this?
To insert records in HeaderTbl from MIVTable use this: (HID should be auto increment)
INSERT INTO HeaderTbl
([MIVID], [TotalQuantity], [TotalValue])
SELECT MIVID, SUM(Quantity), SUM(Value) FROM MIVTable GROUP BY MIVID;
To insert records in DetailTbl from HeaderTbl and MIVTable use this:
INSERT INTO DetailTbl
([HID], [MIVID], [Quantity], [Value])
SELECT H.HID, M.*
FROM HeaderTbl H
INNER JOIN MIVTable M
ON H.MIVID = M.MIVID;
Look at this SQLFiddle
Here you need to use INSERT INTO SELECT statement to insert data from one table to another. You can also use JOIN in such statement as I did it for DetailTbl.
You would generate the HeaderTbl using RANK() SQL Server function, as follows:
SELECT RANK() OVER (ORDER BY MIVID) as HID, MIVID, TotalQuantity, TotalValue
FROM
(
SELECT
MIVID,
SUM(Quantity) as TotalQuantity,
SUM(Value) as TotalValue
FROM MIVTable GROUP BY MIVID
) AS A
and the Detail table using the ROW_NUMBER() SQL Server function, as follows:
SELECT
ROW_NUMBER() OVER (ORDER BY MIVID) AS HID,
MIVID,
Quantity,
Value
FROM MIVTable

sql server 2005 wrong output

I have 3 table stock,inward,issue
Stock table's columns and data :
part_no | part_name | totalqty
10100 ciol 30
112233 abc 20
123456 coper 50
inward table :
part_no | qty
123456 10
123456 20
10100 20
112233 15
10100 25
issue table :
part_no | qty
112233 20
112233 15
123456 10
112233 25
10100 40
10100 20
my desired output :
part_no | part_name |inwardQty |issueQty
10100 coil 45 60
112233 abc 15 60
123456 coper 30 10
following is the query i have written,but not giving my desired output
select s.part_no,s.part_name,sum(i.qty) as inwardQty,sum(p.qty)as issueQty
from stock s
left join inward i on s.part_no = i.part_no
left join issue p on s.part_no = p.part_no
group by
s.part_no,s.part_name
getting following output by this query :
part_no | part_name |inwardQty |issueQty
10100 coil 90 120
112233 abc 45 60
123456 coper 30 20
The problem is that you're matching every row for inward with every row for issue, for which they're dealing with the same part. I think subqueries would be best here:
select s.part_no,s.part_name,i.qty as inwardQty,p.qty as issueQty
from stock s
left join
(select part_no,sum(qty) as qty from inward group by part_no) i on s.part_no = i.part_no
left join
(select part_no,sum(qty) as qty from issue group by part_no) p on s.part_no = p.part_no
So now, there's only one (or zero) rows to join in each of the joins, and you don't get a cartesian product.
Try this query:
SELECT
s.part_no, s.part_name,
InwardQty = (SELECT SUM(qty) FROM #inward i WHERE i.part_no = s.part_no),
IssueQty = (SELECT SUM(qty) FROM #issue p WHERE p.part_no = s.part_no)
FROM
dbo.stock s
GROUP BY
s.part_no, s.part_name
Gives me exactly your desired output.