MySQL calculation within query - mysql

My current query looks like this:
SELECT * FROM `Entrys` WHERE `Timestamp` > 1469308755 AND `Timestamp` < 1469308765 AND (`Exchange` = 1 OR `Exchange` = 2) AND `Market` = 1
It gives me the following result:
For each timestamp value (1469308756 and 1469308761) , I want to calculate the spreads between the prices like this:
For each timestamp-value
For each Exchange
For each Other-Exchange
Divide Exchanges price where type = 2 by Other-Exchanges price where type = 1
This is the best I can explain it. If you don't understand it please leave a comment and I'll try to explain it better.
With the above data it should work like this:
Format: EnId.Field
943.Price / 940.Price
944.Price / 939.Price
961.Price / 985.Price
962.Price / 957.Price
The calculated numbers should be the output of the query.
My SQL skills are way to low for that. Is it even possible to do such calculation inside a single query?

You need to use a JOIN. A JOIN is useful when you want data from two different rows to be referenced in the same expression (either an expression in the WHERE clause or an expression in the select-list).
So you need to join a row to another row that satisfies these conditions:
the same timestamp
a different exchange
the first row is type=2 and the second row is type=1
When you're doing a self-join like this one, you must use table aliases. I will use "numerator" and "denominator" for the two rows.
SELECT numerator.timestamp, numerator.price / denominator.price AS spread
FROM Entrys AS numerator
JOIN Entries AS denominator ON numerator.timestamp=denominator.timestamp
AND numerator.exchange <> denominator.exchange
AND numerator.type = 2 AND denominator.type = 1;

Related

MySQL - Separating data within 1 column into 3 separate columns for a report

We have a report to track how many edits our sales reps are doing. The current query to pull the number of edits on all 3 pages is below. We didn't care before which page they were making edits on, but now we want to see which pages they are make those edits on.
We are wanting to have 3 different columns: bhns, hns, chns, show up on the report and need to modify this query to show the different columns. So, split the 1 column (customer_edits) into 3 columns base on page.
SELECT
count( `database2`.`sales_edits`.`id` ) AS `customer_edits`,
`database2`.`sales_edits`.`rep` AS `rep`
FROM
`database2`.`sales_edits`
WHERE
((
cast( `database2`.`sales_edits`.`date` AS date ) = curdate())
AND ((
`database2`.`sales_edits`.`page` = 'chs'
)
OR ( `database2`.`sales_edits`.`page` = 'chns' )
OR ( `database2`.`sales_edits`.`page` = 'bhns' )))
GROUP BY
`database2`.`sales_edits`.`rep`
sales_edit table:
It looks like you want conditional aggregation:
select
rep,
sum(page = 'chs') customer_edits_chs,
sum(page = 'chns') customer_edits_chns,
sum(page = 'bhns') customer_edits_bhns
from database2.sales_edits
where date = current_date and page in ('chs', 'chns', 'bhns')
group by rep
Your original code looks more complicated that it needs to:
no need to prefix all columns with the schema and table name - a single table comes into play anyway (and if you had more than one, then you should use table aliases to shorten the code)
the date casting seems unecessary; MySQL happily understands any string in 'yyyy-mm-dd' format as a date
the repeated or conditions can be shortened with in
it is probably unneeded to surround all identifiers with backticks, while they do not contain special characters

SQL Combining fields in one table

There is a script that displays two tables. Names of type String and counting of type Long.
How can I combine the same fields “Out of stock” in one field and separate fields “marriage”, “re-sorting” in one field “marriage / re-sorting” in one table. In doing so, save the types of two tables and get the combined values ​​in the new fields. And how not to display extra fields, for example, a form for employees, etc.
I know that you can use the CASE, WHEN, THEN structure. But I don’t understand how to correctly describe it in my script.
SELECT rl.reason AS reject_reason, COUNT(*)
FROM
mp.reservation_log AS rl
JOIN
mp.store AS st ON rl.store_id = st.md_id
JOIN mp.order_item oi ON oi.reserve_id=rl.reservation_id
JOIN mp.sku s ON s.id=oi.item_id
JOIN mp.product p ON p.id=s.product_id
WHERE rl.created_at > DATE(NOW()) - INTERVAL 1 MONTH AND rl.is_successful=0
GROUP BY rl.reason;
Table example:
table example
It seems like you want to combine several reasons in the same group.
You can use a case expression as a no-aggregated column for this, like so:
select
case
when r1.reason in ('marriage', 're-sorting') then 'marriage/re-sorting'
else r1.reason
end real_reason,
count(*) cnt
from ...
where rl.created_at > current_date - interval 1 month and rl.is_successful = 0
group by real_reason
Side note: DATE(NOW()) is better written CURRENT_DATE .

Sql: Find sum of column from second table using date from first table

I've been struggling to build a query that calculate the sum of column called 'TIDAL_VOLUME' with respect to date value that's coming from another table.
Please see the content of the Table_1:
Please see the content of the Table_2:
Note: TIDAL_VOLUME might have NULL as well.
Now, the start time for O2_Device value 'Endotracheal tube' is '2013-08-06 08:10:05' for same HADM_ID and SUBJECT_ID. and end time is whenever new O2_Device value comes in. In this case which is 'Nasal cannula'. Which means start time for 'Endotracheal tube' is '2013-08-06 08:10:05' and end time is '2013-08-06 10:15:05' for HADM_ID = 1 and SUBJECT_ID = 100.
Using that start time and end time criteria, I have to look for TIDAL_VALUE in Table_2. In this example it's 700, 800. Ans for TIDAL_VOLUME is 1500.
Please see the resultant output look like this:
Thanks in advance.
If you can add End_Time to the first table, you can use BETWEEN when you join the tables.
SELECT t1.HADM_ID, t1.Subject_ID, t1.ChartTime, SUM(t2.tidal_volume) AS tidal_volume
FROM Table_1 AS t1
JOIN Table_2 AS t2
ON t1.HADM_ID = t2.HADM_ID
AND t1.Subject_ID = t2.Subject_ID
AND t2.ChartTime BETWEEN t1.ChartTime AND t1.End_Time
GROUP BY t1.HADM_ID, t1.Subject_ID, t1.ChartTime

Using results of one query into the next with unlike column names

My Platform is MySql
I have two queries that I need to combine, using the first query as a type of filter for the second query.
Query 1:
SELECT * FROM INVENTORY
WHERE INV_ID = 1
AND FSCL_YR = 2017
From this query we will get results back that includes a column named STR_NBR.
Which we then want to use in the second query as 'If the store number appears in the first query, give me the results where it shows in the second'. The second query tables use the column name SND_LOC_NBR instead of STR_NBR.
Query 2:
SELECT * FROM Transfer A
LEFT JOIN Transfer_Detail B
ON A.XFER_NBR = B.XFER_NBR
WHERE A.XFER_NBR = B.XFER_NBR
AND A.XFER_STAT_IND IN ('S','C')
AND (where the SND_LOC_NBR needs to match STR_NBRs found from Query 1)
Try this:
SELECT * FROM Transfer A
LEFT JOIN Transfer_Detail B
ON A.XFER_NBR = B.XFER_NBR
WHERE A.XFER_STAT_IND IN ('S','C')
AND SND_LOC_NBR IN
(SELECT STR_NBR FROM INVENTORY
WHERE INV_ID = 1 AND FSCL_YR = 2017 )

Query to sum some of the values

Ive got a simple query that is used on a search. My problem is with this query is that as the records in mysql are added everytime there is a transaction, the query returns a list of data when there could only be one or a few more rows instead of a lot more.
SQLFliddle
As you can see here - the query returns a lot of rows, where I want it to return
BLSH103 A001A 31 24/01/2014
Can the qty where the product name & pallet space are the same be summed? And then show the largest date?
just use a sum function on t.Quantity (and a group by clause)
SELECT (t.ProductName) as Pname ,(s.PalletSpace) as PSpace, sum(t.Quantity) as Qty,(t.TransactionDate) as Transac
FROM PalletSpaces s
JOIN ProductTrans t
ON s.PalletSpaceID = t.PalletSpace
WHERE t.ProductName LIKE 'BLSH103' OR s.PalletSpace LIKE 'BLSH103'
group by
Pname,
pSpace,
Transac -- if you want to group by date also...
By the way, using LIKE this way (without %) doesn't make much sense...
see SqlFiddle
You just need to use GROUP BY and SUM in this way:
SELECT (t.ProductName) as Pname ,(s.PalletSpace) as PSpace, SUM(t.Quantity) as Qty,(t.TransactionDate) as Transac
FROM PalletSpaces s
JOIN ProductTrans t
ON s.PalletSpaceID = t.PalletSpace
WHERE t.ProductName LIKE 'BLSH103' OR s.PalletSpace LIKE 'BLSH103'
GROUP BY t.ProductName, s.PalletSpace;