I have an sql query which shows the delivery details of a vehicle. ( it uses greatest to fetch max value from a range of colums for each vehicle stop)
SELECT deliveryid AS deliverynumber, loadid1 AS loadnumberdate,
haulieraccepted AS haulier,
greatest(drop1arrivedatetime, drop2arrivedatetime, drop3arrivedatetime,
drop4arrivedatetime, drop5arrivedatetime) AS planneddate,
date(greatest(ActualDrop1Arrive, ActualDrop2Arrive, ActualDrop3Arrive,
ActualDrop4Arrive, ActualDrop5Arrive )) AS actualenddate,
mitigation
FROM deliverydetails
WHERE deliveryid=44
the output is
deliverynumber | loadnumberdate | haulier | planneddate | actualenddate | mitigation
44 | 484487 | stols transport | 2011-11-26 15:50:00 | 2011-11-26 | customerdelay
How can I add to the mysql query to compare columns 'planneddate' and 'actualenddate'? if the dates are the same then set the query field to 'ontime' else if actualenddate>planneddate then 'deliverylate'. So ideally I want the following output:
deliverynumber | loadnumberdate | haulier | planneddate | actualenddate | mitigation | Status
44 | 484487 | stols transport | 2011-11-26 15:50:00 | 2011-11-26 | customerdelay | ontime.
Thanks for the assistance.
You can use a CASE statement or IF function. Perhaps something like:
SELECT ...., IF(actualenddate>planneddate,'deliverylate','ontime') AS status FROM ....
use mysql if condition and date conversion function to check and display according to....
You can wrap your original query as a subquery. This will rename the columns. Then, use a case ... then clause to add the column.
Assuming your original query works just fine, it would look like this:
select
*,
case when (... some comparison on 'planneddate' and 'actualenddate' ...)
then <true output>
else <false output> end
from
(<your original query>) as myalias;
The trick is that the columns from the subquery are renamed, allowing you to use their new names (planneddate and actualenddate).
Related
Lately, I have been learning how to use SQL in order to process data. Normally, I would use Python for that purpose, but SQL is required for the classes and I still very much struggle with using it comfortably in more complicated scenarios.
What I want to achieve is the same result as in the following screenshot in Excel:
Behaviour in Excel, that I want to implement in SQL
The formula I used in Excel:
=SUMIF(B$2:B2;B2;C$2:C2)
Sample of the table:
> select * from orders limit 5;
+------------+---------------+---------+
| ID | clientID | tonnage |
+------------+---------------+---------+
| 2005-01-01 | 872-13-44-365 | 10 |
| 2005-01-04 | 369-43-03-176 | 2 |
| 2005-01-05 | 408-24-90-350 | 2 |
| 2005-01-10 | 944-16-93-033 | 5 |
| 2005-01-11 | 645-32-78-780 | 14 |
+------------+---------------+---------+
The implementation is supposed to return similar results as following group by query:
select
orders.clientID as ID,
sum(orders.tonnage) as Tonnage
from orders
group by orders.clientID;
That is, return how much each client have purchased, but at the same I want it to return each step of the addition as separate record.
For an instance:
Client A bought 350 in the first order and then 231 in the second one. In such case the query would return something like this:
client A - 350 - 350 // first order
client A - 281 - 581 // second order
Example, how it would look like in Excel
I have already tried to use something like:
select
orders.clientID as ID,
sum(case when orders.clientID = <ID> then orders.tonnage end)
from orders;
But got stuck quickly, since I would need to somehow dynamically change this <ID> and store it's value in some kind of temporary variable and I can't really figure out how to implement such thing in SQL.
You can use window function for running sum.
In your case, use like this
select id, clientID, sum(tonnage) over (partition by clientID order by id) tonnageRunning
from orders
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=13a8c2d46b5ac22c5c120ac937bd6e7a
I'm having some problems with the data types of some tables.
For example, I have:
+-------+----------+-------------+----------+--------------+
| Code | Money1 | Money2 | Quantity | Total |
+-------+----------+-------------+----------+--------------+
| 10001 | 100.4334 | 200.3444332 | 100 | 50,432.74642 |
+-------+----------+-------------+----------+--------------+
But I only want 2 digits in each column. I know how to do it from the Table (choosing Number -> Standard -> 2 decimals), but when I compile the query that corresponds to that Table, it breaks again.
I think I have to put CLng(), CInt() and that stuff in the query. Where? In SELECT, FROM, TO?. Is that OK? How "Standard, 2 digits" is called in that nomenclature?
Use Round([Money1], 2) for your columns in the query or - if you are serious about rounding - the RoundMid function here:
GitHub VBA.Round
Then use:
Select
Code,
RoundMid([Money1], 2) As Money_1,
RoundMid([Money2], 2) As Money_2,
Quantity,
RoundMid([Total], 2) As Total2
From
YourTable
I have a query where a previous day's balances are supposed to be subtracted from the current day's balances. Here is my SQL
SELECT [206_Src_045].[Eff Date], [103_Wire_Log].[Eff Date], [103_Wire_Log].Portfolio, [206_Src_045].Activity, [206_Src_045].[SumOfUSD Balance] AS Today_Amount, [103_Wire_Log].Balance AS Yesterday_Amount, Format([Today_Amount]-[Yesterday_Amount],"Fixed") AS Difference
FROM 206_Src_045 INNER JOIN (103_Wire_Log INNER JOIN (54_Port_Activity INNER JOIN 205_Wire_Details_Clean ON [54_Port_Activity].MetlifePortCode = [205_Wire_Details_Clean].Portfolio) ON [103_Wire_Log].Portfolio = [205_Wire_Details_Clean].Portfolio) ON [206_Src_045].Activity = [54_Port_Activity].ActivityCode
WHERE ((([206_Src_045].[Eff Date])=DMax("[Eff Date]","206_Src_045")) AND ((DateDiff('d',[206_Src_045].[Eff Date],[103_Wire_Log].[Eff Date]))="1") AND (([205_Wire_Details_Clean].Negative)=IIf([206_Src_045].[SumOfUSD Balance]-[103_Wire_Log].[Balance]<0,"Yes","No")));
((DateDiff('d',[206_Src_045].[Eff Date],[103_Wire_Log].[Eff Date]))= "1"
Changes the output from
--------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------
| 206_Src_045.Eff | 103_Wire_Log.Eff Date | Portfolio | Activity | Today_Amount | Yesterday_Amount | Difference |
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| 06/15/2017 | 06/13/2017 | 7TZ | 4200007025 | -10000 | 21770.83 | -31770.83 |
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| 06/15/2017 | 06/14/2017 | 7TZ | 4200007025 | -10000 | 1000 | -11000.00 |
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
To nothing, when the second line, with dates 6/15/2017 and 6/14/2017, is the correct output. How am I using it wrong? I used it in a similar fashion in another query correctly.
Double check the order of your dates. DateDiff will return a negative number if the dates are in the reverse order. To resolve the issues, either wrap the call in Abs() like Abs(DateDiff(...)) = 1 or use DateDiff(...) In (-1, 1)
A final debugging hint: It can be worth putting a problematic expression in the select clause so that you can actually see the values that an expression is returning: SELECT DateDiff('d',[206_Src_045].[Eff Date],[103_Wire_Log].[Eff Date]) As ElapsedDays, ... This would have revealed a value of -1.
my ms access table like this:
ID | Group | Detail(A) | Detail(B)
1 | A | ABC |
2 | A | DEF |
3 | B | | GHI
How can my access sql select Detail(A) as 'Details' when Group=A, Detail(B) as 'Details' when Group=B ?
Thanks
You can use immediate if, IIF.
SELECT IIf(Group="A",DetailA,DetailB) As Detail
FROM Table
I like Remou's answer, the IIF is a good simple function, however if you are comparing multiple values, it could quickly grow to fit all the IIF's, as an alternative in a multi scenario or even for singles values if you wish you can use the Switch method:
SELECT Switch(Group="A", DetailA, Group="B", DetailB) AS Detail
FROM Table
Then you would simply keep adding e.g. Group="C", DetailC etc
I've a database called test and i've tables called x,y,z.
How do i select x,y,z and there is a column called date IN X,Y,Z check whether there is a particular date.
Is there any build in function that does this?
update
SELECT column date from all tables which is in a database called test
Thanks in advance!!
As far as I know, in SQL you cannot 'select a table', you can select some
column(s) from one or many tables at once. The result of such a query is an another table (temporary table) that you retrieve the data from.
Please be more specific about what exactly you want to do (e.g.: "I want to select a column 'z' from table 'tableA' and column 'y' from table 'tableB'") - then I'm sure your question has a pretty simple answer :)
SELECT x.date AS x_date, y.date AS y_date, z.date AS z_date FROM x,y,z;
That produces a result:
+---------+---------+---------+
| x_date | y_date | z_date |
+---------+---------+---------+
| | | |
| | | |
+---------+---------+---------+
Alternatively you can get everything in one column by ussuing a query:
SELECT date FROM x
UNION ALL
SELECT date FROM y
UNION ALL
SELECT date FROM z;
That produces a result:
+-------+
| date |
+-------+
| |
| |
+-------+
In the example above you would get also duplicate values in the single column. If you want to avoid duplicates replace 'UNION ALL' with 'UNION'
I'm still not sure if I undestood what you really want ot achieve, but I still hope that helps
Also take a look at:
http://www.w3schools.com/sql/sql_union.asp
http://www.sql-tutorial.net/SQL-JOIN.asp