This question already has answers here:
Select first row in each GROUP BY group?
(20 answers)
Closed 2 years ago.
Right now I have this query:
SELECT DISTINCT
stock_picking.id as delivery_order_id,
sale_order.id as sale_order_id,
sale_order.name as sale_order_name,
stock_picking.origin as stock_picking_origin,
stock_picking.name as stock_picking_name,
stock_picking.create_date as stock_picking_create_date,
sub.count_origin as sale_order_delivery_order_done_count
FROM
(
SELECT
origin,
COUNT(origin) as count_origin
FROM stock_picking
WHERE state = 'done'
GROUP BY origin
HAVING COUNT(origin) > 1
ORDER BY origin
) sub
JOIN sale_order ON sale_order.name = sub.origin
JOIN account_invoice ON account_invoice.origin = sale_order.name
JOIN stock_picking ON stock_picking.origin = sale_order.name
WHERE
account_invoice.create_date >= '04/17/20' AND
sale_order.create_date <= '04/01/20 07:00' AND
sale_order.create_date >= '03/01/20'
ORDER BY sale_order.name
;
It returns:
+-------------------+---------------+-----------------+----------------------+--------------------+----------------------------+--------------------------------------+
| delivery_order_id | sale_order_id | sale_order_name | stock_picking_origin | stock_picking_name | stock_picking_create_date | sale_order_delivery_order_done_count |
+-------------------+---------------+-----------------+----------------------+--------------------+----------------------------+--------------------------------------+
| 2053131 | 5840046 | 3258428 | 3258428 | WH/OUT/1804215 | 2020-03-01 07:10:32.144694 | 2 |
| 2071149 | 5840046 | 3258428 | 3258428 | WH/OUT/1819605 | 2020-03-03 18:00:25.208632 | 2 |
| 2154480 | 5840046 | 3258428 | 3258428 | WH/OUT/1894584 | 2020-03-11 08:39:33.514114 | 2 |
| 2053494 | 5840408 | 3258728 | 3258728 | WH/OUT/1804574 | 2020-03-01 07:41:26.728154 | 2 |
| 2105133 | 5840408 | 3258728 | 3258728 | WH/OUT/1849288 | 2020-03-07 13:59:10.049683 | 2 |
| 2192492 | 5840408 | 3258728 | 3258728 | WH/OUT/1929553 | 2020-03-13 09:10:26.18469 | 2 |
| 2061022 | 5861189 | 3279458 | 3279458 | WH/OUT/1811084 | 2020-03-02 14:37:35.803326 | 2 |
| 2170656 | 5861189 | 3279458 | 3279458 | WH/OUT/1909477 | 2020-03-12 08:57:15.434752 | 2 |
| 2072002 | 5885577 | 3294059 | 3294059 | WH/OUT/109633 | 2020-03-04 02:44:03.302924 | 2 |
| 2130430 | 5885577 | 3294059 | 3294059 | WH/OUT/114259 | 2020-03-10 03:13:58.33838 | 2 |
+-------------------+---------------+-----------------+----------------------+--------------------+----------------------------+--------------------------------------+
I want to make sure that the column sale_order_id is unique, but picked from the least delivery_order_id and not aggregated.
I want to have a result like this:
+-------------------+---------------+-----------------+----------------------+--------------------+----------------------------+--------------------------------------+
| delivery_order_id | sale_order_id | sale_order_name | stock_picking_origin | stock_picking_name | stock_picking_create_date | sale_order_delivery_order_done_count |
+-------------------+---------------+-----------------+----------------------+--------------------+----------------------------+--------------------------------------+
| 2053131 | 5840046 | 3258428 | 3258428 | WH/OUT/1804215 | 2020-03-01 07:10:32.144694 | 2 |
| 2053494 | 5840408 | 3258728 | 3258728 | WH/OUT/1804574 | 2020-03-01 07:41:26.728154 | 2 |
| 2061022 | 5861189 | 3279458 | 3279458 | WH/OUT/1811084 | 2020-03-02 14:37:35.803326 | 2 |
| 2072002 | 5885577 | 3294059 | 3294059 | WH/OUT/109633 | 2020-03-04 02:44:03.302924 | 2 |
+-------------------+---------------+-----------------+----------------------+--------------------+----------------------------+--------------------------------------+
You can use distinct on. Your query is complicated, so I'll encapsulate it in a CTE:
with q as (
. . .
)
select distinct on (sale_order_id) q.*
from q
order by sale_order_id, delivery_order_id;
I have made a Crosstab Query that should give information about the total working hours in each day for every Vessel we had in our small harbor.
my query:
TRANSFORM Sum(Main.WorkingH) AS SumOfWorkingH
SELECT DateValue([DeptDate]) AS [Date]
FROM Vessels INNER JOIN Main ON Vessels.ID = Main.VesselID
GROUP BY DateValue([DeptDate])
ORDER BY DateValue([DeptDate])
PIVOT Vessels.Vessel;
the problem here is this query is returning the total working hours start from departure date
| +---------------+--------+----+----+----+----+----+----+ |
| | | | | | | | | | |
| +---------------+--------+----+----+----+----+----+----+ |
| | Date | A1 | A2 | A3 | F3 | F4 | F5 | F6 | |
| | 26-May-17 | | | 32 | 29 | | | | |
| | 27-May-17 | 3 | 13 | | | | | | |
| | 28-May-17 | | | | | | | 73 | |
| | 29-May-17 | | | | 12 | 6 | 27 | | |
| | 01-Jun-17 | | | 10 | | 7 | 41 | | |
| | 02-Jun-17 | | 2 | 15 | 5 | | | | |
| | 03-Jun-17 | | 4 | | | | | | |
| +---------------+--------+----+----+----+----+----+----+ |
The desired Result
when a vessel leaves at 6/1 9pm and arrive back at 6/3 10am. This should appear as following:
6/1-->3Hours
6/2-->24Hours
6/3-->10Hours
**NOT** 6/1-->37Hours as in the previous table.
This is how it should look like
| +----------------+-----+----+----+----+--------+----+----+ |
| | Date | A1 | A2 | A3 | F3 | F4 | F5 | F6 | |
| +----------------+-----+----+----+----+--------+----+----+ |
| | 26-May-17 | | | 5 | 7 | | | | |
| | 27-May-17 | 3 | 13 | 24 | 21 | | | | |
| | 28-May-17 | | | 2 | | | | 9 | |
| | 29-May-17 | | | | 12 | 6 | 8 | 24 | |
| | 30-May-17 | | | | | | 18 | 24 | |
| | 31-May-17 | | | | | | | 15 | |
| | 01-Jun-17 | | | 10 | | 7 | 0 | | |
| | 02-Jun-17 | | 2 | 15 | 5 | 24 | | | |
| | 03-Jun-17 | | 4 | | | | 16 | | |
| +----------------+-----+----+----+----+--------+----+----+ |
These values are not accurate (I wrote them by hand), but I think you got the Idea
The Suggested Solution
while trying to fix this problem I made the following code which takes the
Public Function HoursByDate1(stTime, EndTime)
For dayloop = Int(EndTime) To Int(stTime) Step -1
If dayloop = Int(stTime) Then
WorkingHours = Hour(dayloop + 1 - stTime)
ElseIf dayloop = Int(EndTime) Then
WorkingHours = Hour(EndTime - dayloop)
Else
WorkingHours = 24
End If
HoursByDate1 = WorkingHours
Debug.Print "StartDate: " & stTime & ", EndDate:" & EndTime & ", The day:" & dayloop & " --> " & WorkingHours & " hours."
Next dayloop
End Function
It prints the data as following:
which is exactly what I want
But when I try to call this function from my query, It gets only the last value for each trip. as following:
| +-----------+----+----+----+----+----+----+----+ |
| | Date | A1 | A2 | A3 | F3 | F4 | F5 | F6 | |
| +-----------+----+----+----+----+----+----+----+ |
| | 5/26/2017 | | | 5 | 7 | | | | |
| | 5/27/2017 | 15 | 19 | | | | | | |
| | 5/28/2017 | | | | | | | 9 | |
| | 5/29/2017 | | | | 8 | 7 | 8 | | |
| | 6/1/2017 | | | 3 | | 6 | 0 | | |
| | 6/2/2017 | | 8 | 8 | 19 | | | | |
| | 6/3/2017 | | 9 | | | | | |
I seek any Solution: From VBA side of things or SQL Query Side.
Sorry for the very long question, but I wanted to show my effort on the subject because every time I am told that this is not enough Information
I'm filling empty arrivals time in a bus timetable, I have start,end and some midpoints times, I do by calculating average speed between start and end route, but results are inexact, so must use intervals speed to compute arrivals times.
General Timetable shown in First Code Snippet, please run to see table, and Computed arrival times for Intervals in Second Code Snippet .
What I'm trying to do is to fill in av_speed ingeneral timetable with Intervals average speed, i.e. put 251.17 into timetable stops_sequences 1 to 5, 230.68 into sequences 6 to 10 and so on.
+============+===============+==============+==========+===========+===========+==========+
| stoptimeid | stop_sequence | arrival_time | distance | dist_trav | time_trav | av_speed |
+============+===============+==============+==========+===========+===========+==========+
| 54689 | 1 | 6:05:00 | 0,00 | | | 220,98 |
| 54690 | 2 | | 0,35 | | | 220,98 |
| 54691 | 3 | | 0,49 | | | 220,98 |
| 54692 | 4 | | 0,91 | | | 220,98 |
| 54693 | 5 | 6:10:00 | 1,19 | | | 220,98 |
| 54694 | 6 | | 1,50 | | | 220,98 |
| 54695 | 7 | | 1,67 | | | 220,98 |
| 54696 | 8 | | 1,96 | | | 220,98 |
| 54697 | 9 | | 2,16 | | | 220,98 |
| 54698 | 10 | 6:15:00 | 2,49 | | | 220,98 |
| 54699 | 11 | | 2,64 | | | 220,98 |
| 54700 | 12 | | 3,11 | | | 220,98 |
| 54701 | 13 | | 3,79 | | | 220,98 |
| 54702 | 14 | | 4,14 | | | 220,98 |
| 54703 | 15 | | 4,39 | | | 220,98 |
| 54704 | 16 | | 4,96 | | | 220,98 |
| 54705 | 17 | | 5,10 | | | 220,98 |
| 54706 | 18 | 6:25:00 | 5,21 | | | 220,98 |
+============+===============+==============+==========+===========+===========+==========+
+============+===============+==============+==========+===========+===========+==========+
| stoptimeid | stop_sequence | arrival_time | distance | dist_trav | time_trav | av_speed |
+============+===============+==============+==========+===========+===========+==========+
| 54689 | 1 | 6:05:00 | 0,00 | | | |
| 54693 | 5 | 6:10:00 | 1,19 | 1,194423 | 300 | 251,17 |
| 54698 | 10 | 6:15:00 | 2,49 | 1,300520 | 300 | 230,68 |
| 54706 | 18 | 6:25:00 | 5,21 | 2,715214 | 600 | 220,98 |
+============+===============+==============+==========+===========+===========+==========+
Have checked the use of a CASE function that fills in descending order, fills 18 to 1, then fills 10 to 5 and finally 5 to 1, so final result it's ok.
This is what I tried but only fill with only one av_speed, the last one.
CREATE OR REPLACE VIEW arrivaltime_check AS
SELECT
CASE
WHEN arrivaltime.stop_sequence<=foo.stop_sequence THEN foo.av_speed
ELSE foo.av_speed END,foo.trip_id2,foo.stop_sequence
FROM
public.arrivaltime,
(SELECT
b.rid,
b.trip_id2,
b.stoptimeid,
b.stop_sequence,
b.arrival_time,
extract(epoch from (b.arrival_time)) as time_epoch,
b.distance,
b.distance -lag(b.distance,1) over (partition by b.trip_id2 ) as dist_trav,
b.time_epoch -lag(b.time_epoch,1) over (partition by b.trip_id2 ) as time_trav,
(b.time_epoch -lag(b.time_epoch,1) over (partition by b.trip_id2 ))/(b.distance -lag(b.distance,1) over (partition by b.trip_id2 )) as av_speed
from public.timecalc1 b
order by b.trip_id2,b.stop_sequence desc) foo;
foo subquery only computes values when arrivaltimes is not null,
How can I fill in timetable with intervals av_speed?
I have a base table where I need to calculate the difference between two dates based on the type of the entry.
tblA
+----------+------------+---------------+--------------+
| TypeCode | Log_Date | Complete_Date | Pending_Date |
+----------+------------+---------------+--------------+
| 1 | 18/04/2016 | 19/04/2016 | |
| 2 | 10/04/2016 | 18/04/2016 | 15/04/2016 |
| 3 | 12/04/2016 | 19/04/2016 | |
| 4 | 15/04/2016 | 17/04/2016 | 16/04/2016 |
| 5 | 16/04/2016 | 21/04/2016 | |
| 1 | 19/04/2016 | 20/04/2016 | |
| 2 | 20/03/2016 | 31/03/2015 | |
| 3 | 25/03/2016 | 28/03/2016 | |
| 4 | 26/03/2016 | 27/03/2016 | |
| 5 | 27/03/2016 | 30/03/2016 | |
+----------+------------+---------------+--------------+
I have another look up table which has the column names to be considered based on the TypeCode.
tblB
+----------+----------+---------------+
| TypeCode | DateCol1 | DateCol2 |
+----------+----------+---------------+
| 1 | Log_Date | Complete_Date |
| 2 | Log_Date | Pending_Date |
| 3 | Log_Date | Complete_Date |
| 4 | Log_Date | Pending_Date |
| 5 | Log_Date | Complete_Date |
+----------+----------+---------------+
I am doing a simple DATEDIFF between two dates for my calculation. However I want to lookup which columns to consider for this calculation from tblB and apply it on tblA based on the TypeCode.
Resulting table:
For example: When the TypeCode is 2 or 4 then the calculation should be DATEDIFF(d, Log_Date, Pending_Date), otherwise DATEDIFF(d, Log_Date, Complete_Date)
+----------+------------+---------------+--------------+----------+
| TypeCode | Log_Date | Complete_Date | Pending_Date | Cal_Days |
+----------+------------+---------------+--------------+----------+
| 1 | 18/04/2016 | 19/04/2016 | | 1 |
| 2 | 10/04/2016 | 18/04/2016 | 15/04/2016 | 5 |
| 3 | 12/04/2016 | 19/04/2016 | | 7 |
| 4 | 15/04/2016 | 17/04/2016 | 16/04/2016 | 1 |
| 5 | 16/04/2016 | 21/04/2016 | | 5 |
| 1 | 19/04/2016 | 20/04/2016 | | 1 |
| 2 | 20/03/2016 | 31/03/2015 | | |
| 3 | 25/03/2016 | 28/03/2016 | | 3 |
| 4 | 26/03/2016 | 27/03/2016 | | |
| 5 | 27/03/2016 | 30/03/2016 | | 3 |
+----------+------------+---------------+--------------+----------+
Any help would be appreciated. Thanks.
Use JOIN with CASE expression:
SELECT
a.*,
Cal_Days =
DATEDIFF(
DAY,
CASE
WHEN b.DateCol1 = 'Log_Date' THEN a.Log_Date
WHEN b.DateCol1 = 'Complete_Date' THEN a.Complete_Date
ELSE a.Pending_Date
END,
CASE
WHEN b.DateCol2 = 'Log_Date' THEN a.Log_Date
WHEN b.DateCol2 = 'Complete_Date' THEN a.Complete_Date
ELSE a.Pending_Date
END
)
FROM TblA a
INNER JOIN TblB b
ON b.TypeCode = a.TypeCode
i'm aware that this question has been asked multiple times and I have read those threads to get to where I am now, but those solutions don't seem to be working. I need to have a running total of my ExpectedAmount...
I have the following table:
+--------------+----------------+
| ExpectedDate | ExpectedAmount |
+--------------+----------------+
| 1 | 2485513 |
| 2 | 526032 |
| 3 | 342041 |
| 4 | 195807 |
| 5 | 380477 |
| 6 | 102233 |
| 7 | 539951 |
| 8 | 107145 |
| 10 | 165110 |
| 11 | 18795 |
| 12 | 27177 |
| 13 | 28232 |
| 14 | 154631 |
| 15 | 5566585 |
| 16 | 250814 |
| 17 | 90444 |
| 18 | 105424 |
| 19 | 62132 |
| 20 | 1799349 |
| 21 | 303131 |
| 22 | 459464 |
| 23 | 723488 |
| 24 | 676514 |
| 25 | 17311911 |
| 26 | 4876062 |
| 27 | 4844434 |
| 28 | 4039687 |
| 29 | 1418648 |
| 30 | 4366189 |
| 31 | 9028836 |
+--------------+----------------+
I have the following SQL:
SELECT a.ExpectedDate, a.ExpectedAmount, (SELECT SUM(b.ExpectedAmount)
FROM UnpaidManagement..Expected b
WHERE b.ExpectedDate <= a.ExpectedDate)
FROM UnpaidManagement..Expected a
The result of the above SQL is this:
+--------------+----------------+--------------+
| ExpectedDate | ExpectedAmount | RunningTotal |
+--------------+----------------+--------------+
| 1 | 2485513 | 2485513 |
| 2 | 526032 | 9480889 |
| 3 | 342041 | 46275618 |
| 4 | 195807 | 59866450 |
| 5 | 380477 | 60246927 |
| 6 | 102233 | 60349160 |
| 7 | 539951 | 60889111 |
| 8 | 107145 | 60996256 |
| 10 | 165110 | 2650623 |
| 11 | 18795 | 2669418 |
| 12 | 27177 | 2696595 |
| 13 | 28232 | 2724827 |
| 14 | 154631 | 2879458 |
| 15 | 5566585 | 8446043 |
| 16 | 250814 | 8696857 |
| 17 | 90444 | 8787301 |
| 18 | 105424 | 8892725 |
| 19 | 62132 | 8954857 |
| 20 | 1799349 | 11280238 |
| 21 | 303131 | 11583369 |
| 22 | 459464 | 12042833 |
| 23 | 723488 | 12766321 |
| 24 | 676514 | 13442835 |
| 25 | 17311911 | 30754746 |
| 26 | 4876062 | 35630808 |
| 27 | 4844434 | 40475242 |
| 28 | 4039687 | 44514929 |
| 29 | 1418648 | 45933577 |
| 30 | 4366189 | 50641807 |
| 31 | 9028836 | 59670643 |
+--------------+----------------+--------------+
You can tell from the first few values already that the math is all off, but then at some points the math adds up?! I'm Too confused !! Could someone please point me to another solution or to where I have gone wrong with this?
I am using SQL Server 2008.
It is because your ExpectedDate column of type varchar. Try this:
SELECT a.ExpectedDate, a.ExpectedAmount, (SELECT SUM(b.ExpectedAmount)
FROM UnpaidManagement..Expected b
WHERE CAST(b.ExpectedDate as int) <= CAST(a.ExpectedDate as int))
FROM UnpaidManagement..Expected a
Note that it could be inefficient query.
I think this gonna work:
SELECT a.ExpectedDate,
a.ExpectedAmount,
SUM(b.ExpectedAmount) RuningTotal
FROM UnpaidManagement..Expected a
LEFT JOIN UnpaidManagement..Expected b
ON CAST(b.ExpectedDate as int) <= CAST(a.ExpectedDate as int)
GROUP BY a.ExpectedDate, a.ExpectedAmount
AND:
SELECT a.ExpectedDate,
a.ExpectedAmount,
c.RuningTotal
FROM UnpaidManagement..Expected a
CROSS APPLY (
SELECT SUM(b.ExpectedAmount) AS RuningTotal
FROM UnpaidManagement..Expected b
WHERE CAST(b.ExpectedDate as int) <= CAST(a.ExpectedDate as int)
) c