I am trying to write a query to return the sum of totalRxCount that is grouped by zipcode.
I have two tables named fact2 and demographic.
My problem is that in the demographic table there are duplicate rows which affects the sum of totalRxCount.
To avoid duplicates I am wanting to only return results where npiNum is distinct.
Right now I have this working but it is grouping by relId (the primary key).
I cannot figure out a way to group by zipcode since this column and totalRxCount are in separate tables.
When I try this I am getting wrong results since it is counting the duplicate rows.
Here is my query. I am wanting to modify this to return results grouped by zipcode instead of relId.
Any input will be greatly appreciated!
SELECT fact2.relID
, SUM(fact2.`totalRxCount`)
FROM fact2
LEFT
JOIN (
SELECT O1.relId, COUNT(DISTINCT O1.npiNum)
FROM demographic As O1
GROUP BY O1.relId
) AS d1
ON d1.`relId` = fact2.relID
LEFT
JOIN (
SELECT O2.relID, Sum(O2.totalRxCount)
FROM fact2 AS O2
GROUP BY O2.relID
) AS p1
ON p1.relID = d1.relId
WHERE (monthEndDate BETWEEN 201911 AND 202010) GROUP BY fact2.relID;
Results:
+-------+---------------------------+
| relID | SUM(fact2.totalRxCount) |
+-------+---------------------------+
| 2465 | 2 |
+-------+---------------------------+
What I've tried
SELECT zipcode, SUM(fact2.`totalRxCount`)
FROM fact2
INNER JOIN demographic ON demographic.relId=fact2.relID
LEFT JOIN (
SELECT O1.`relId`, COUNT(DISTINCT O1.`npiNum`)
FROM demographic As O1
GROUP BY O1.`relId`
) AS d1
ON d1.`relId` = fact2.`relID`
LEFT JOIN (
SELECT O2.`relID`, Sum(O2.`totalRxCount`)
FROM fact2 AS O2
GROUP BY O2.`relID`
) AS p1
ON p1.`relID` = d1.`relId`
WHERE (`monthEndDate` BETWEEN 201911 AND 202010) GROUP BY zipcode;
This is returning the sum multiplied by number of duplicate rows in demographic.
Results:
+---------+---------------------------+
| zipcode | SUM(fact2.`totalRxCount`) |
+---------+---------------------------+
| 66097 | 4 |
+---------+---------------------------+
^ This should be 2
demographic table:
+-------+---------+------------+------------+-----------+------------+------------------------------------+-------+----------+----------+-----------------+------------+-------+--------------+---------+----------+-----------+--------+-------------+--------+--------+----------------+
| relId | zipcode | providerId | writerType | firstName | middleName | lastName | title | specCode | specDesc | address | city | state | amaNoContact | pdrpInd | pdrpDate | deaNum | amaNum | amaCheckDig | npiNum | terrId | callStatusCode |
+-------+---------+------------+------------+-----------+------------+------------------------------------+-------+----------+----------+-----------------+------------+-------+--------------+---------+----------+-----------+--------+-------------+--------+--------+----------------+
| 2465 | 66097 | | A | | | JEFFERSON COUNTY MEMORIAL HOSPITAL | | | | 408 DELAWARE ST | WINCHESTER | KS | | | | AJ4281096 | | | | 11604 | |
| 2465 | 66097 | | A | | | JEFFERSON COUNTY MEMORIAL HOSPITAL | | | | 408 DELAWARE ST | WINCHESTER | KS | | | | AJ4281096 | | | | 11604 | |
+-------+---------+------------+------------+-----------+------------+------------------------------------+-------+----------+----------+-----------------+------------+-------+--------------+---------+----------+-----------+--------+-------------+--------+--------+----------------+
fact2
+-------+----------+-----------------+-----------+-------------------+----------+------------+------------+--------+------------+--------------+------------+---------------+--------------+-----------+--------------+-------------+-----------+--------------+-------------+
| relID | marketId | marketName | productID | productName | dataType | providerId | writerType | planId | pmtTypeInd | monthEndDate | newRxCount | refillRxCount | totalRxCount | newRxQuan | refillRxQuan | totalRxQuan | newRxCost | refillRxCost | totalRxCost |
+-------+----------+-----------------+-----------+-------------------+----------+------------+------------+--------+------------+--------------+------------+---------------+--------------+-----------+--------------+-------------+-----------+--------------+-------------+
| 2465 | 10871 | GALT PP MONTHLY | 1399451 | ZOLPIDEM TARTRATE | 15 | | A | 900145 | C | 202004 | 1 | 0 | 1 | 30 | 0 | 30 | 139 | 0 | 139 |
| 2465 | 10871 | GALT PP MONTHLY | 1399458 | ESZOPICLONE | 15 | | A | 900145 | C | 202006 | 1 | 0 | 1 | 30 | 0 | 30 | 350 | 0 | 350 |
+-------+----------+-----------------+-----------+-------------------+----------+------------+------------+--------+------------+--------------+------------+---------------+--------------+-----------+--------------+-------------+-----------+--------------+-------------+
Related
i would like to get the Count value from the 3rd table... 1st table has reference id to 2nd table, 2nd table has reference id of 3rd table... in 3rd table has the value... that i need to count...
Table struct:
table1: tbl_rack
+------------+---------+--------+
| rack_id | site_id | status |
+------------+---------+--------+
| R-642 | ST5 | Y |
| R-307 | ST6 | Y |
| R-57 | ST7 | Y |
| 390/6 | ST8 | Y |
| 9706 | ST11 | Y |
table2: tbl_site
+---------+-------------+-----------+
| site_id | customer_id | region_id |
+---------+-------------+-----------+
| ST5 | CM8 | RM4 |
| ST6 | CM8 | RM8 |
| ST7 | CM10 | RM2 |
| ST8 | CM11 | RM12 |
| ST11 | CM8 | RM10 |
table3: tbl_customer
+-------------+----------------------+---------------+
| customer_id | customer_name | customer_type |
+-------------+----------------------+---------------+
| CM8 | LIVI-IN | MODERATE |
| CM10 | PEPE | HIGH |
| CM11 | SANDER | LOW |
| CM12 | TOASTER | MODERATE |
I want to count each customers contains how many Racks where ranks status is 'Y'
expected Result1:
Customer No.of Racks
LIVI-IN 3
OTHERS 2
expected Result2:
Customer Type No.of Racks
Moderate 3
High 1
Low 1
Please, follow below SQL query:
select C.customer_name as 'Customer', count(*) as 'No.of Racks'
from tbl_customer C
left outer join tbl_site TS on TS.customer_id = C.customer_id
left outer join tbl_rack TR on TR.site_id = TS.site_id
group by C.customer_name
order by C.customer_name
Kindly consider the following tables:
invoices
+-----------+----+------------+--------+---------+
| accountid | id | customerid | total | balance |
+-----------+----+------------+--------+---------+
| 1 | 2 | 167909 | 120060 | 120060 |
+-----------+----+------------+--------+---------+
invoices_attributes
+-----------+----+--------------+
| accountid | id | name |
+-----------+----+--------------+
| 1 | 1 | registration |
+-----------+----+--------------+
| 1 | 2 | claimnumber |
+-----------+----+--------------+
| 1 | 3 | jobid |
+-----------+----+--------------+
invoices_attributes_values
+------------------+-------------+-----------+---------------+
| attributevalueid | attributeid | invoiceid | value |
+------------------+-------------+-----------+---------------+
| 1 | 1 | 2 | ABC 126L |
+------------------+-------------+-----------+---------------+
| 2 | 2 | 2 | ABZ123 |
+------------------+-------------+-----------+---------------+
| 3 | 3 | 2 | MARY DOE |
+------------------+-------------+-----------+---------------+
Through the help of Eugen Rieck's original answer I was able to make the following query
SELECT
invoices.accountid,
invoices.id AS invoiceid,
invoices.customerid,
invoices.total,
registration.value AS registration,
claimnumber.value AS claimnumber,
jobid.value as jobid
FROM
invoices
LEFT JOIN invoice_attributes ON invoices.accountid=invoice_attributes.accountid
LEFT JOIN invoice_attribute_values AS registration ON registration.attributeid = invoice_attributes.id AND invoices.id = registration.invoiceid AND invoice_attributes.name = 'registration'
LEFT JOIN invoice_attribute_values AS claimnumber ON claimnumber.attributeid = invoice_attributes.id AND invoices.id = claimnumber.invoiceid AND invoice_attributes.name = 'claimnumber'
LEFT JOIN invoice_attribute_values AS jobid ON jobid.attributeid = invoice_attributes.id AND invoices.id = jobid.invoiceid AND invoice_attributes.name = 'jobid'
Which gave the following result
+-----------+-----------+------------+--------+--------------+-------------+----------+
| accountid | invoiceid | customerid | total | registration | claimnumber | jobid |
+-----------+-----------+------------+--------+--------------+-------------+----------+
| 1 | 2 | 167909 | 120060 | NULL | NULL | MARY DOE |
+-----------+-----------+------------+--------+--------------+-------------+----------+
| 1 | 2 | 167909 | 120060 | NULL | ABZ123 | NULL |
+-----------+-----------+------------+--------+--------------+-------------+----------+
| 1 | 2 | 167909 | 120060 | ABC 126L | NULL | NULL |
+-----------+-----------+------------+--------+--------------+-------------+----------+
When I GROUP BY invoices.id some of the columns (registration, claimnumner or job) will become NULL. I desire the result to be as:
+-----------+-----------+------------+--------+--------------+-------------+----------+
| accountid | invoiceid | customerid | total | registration | claimnumber | jobid |
+-----------+-----------+------------+--------+--------------+-------------+----------+
| 1 | 2 | 167909 | 120060 | ABC 126L | ABZ123 | MARY DOE |
+-----------+-----------+------------+--------+--------------+-------------+----------+
How can the query be modified to get the result above?
SQL has no provision to make the columns dependant on the data. You could however create a query with ALL possible attributes along the lines of
Basically you want to renormalize an EVA structure - this is of course possible:
SELECT
invoices.accountid,
invoices.id AS invoiceid
invoices.customerid,
invoices.total,
jobids.value AS jobid -- one of these lines per attriubute
FROM
invoices
LEFT JOIN invoices_attributes ON invoices.accountid=invoices_attributes.accountid
-- One of the following joins per attribute
LEFT JOIN invoices_attributes_values AS jobids
ON jobids.attr_id=invoices_attributes.attr_id
AND jobids.accountid=invoices.accountid
AND jobids.invoiceid=invoices.id
AND invoices_attributes.attr_name='jobid'
I am trying to join 3 tables but it looks like I am doing something wrong. Also I am not sure if INNER JOIN is a good idea here because there might be some missing corresponding rows in the other tables, but I would still like them to show up as NULL, then maybe LEFT JOIN would be better, but again, I'm doing something wrong.
A quick summary of the table responses:
SELECT geonameid, name, iso_alpha2, admin1_code
FROM maxmind_cities1000
WHERE name LIKE 'tron%' LIMIT 20;
+-----------+------------------------+------------+-------------+
| geonameid | name | iso_alpha2 | admin1_code |
+-----------+------------------------+------------+-------------+
| 1605268 | Tron | TH | 10 |
| 8949073 | Tronca | IT | 03 |
| 3107444 | Tronchón | ES | 52 |
| 8859151 | Tronconal | MX | 21 |
| 2821000 | Tröndel | DE | 10 |
| 3133880 | Trondheim | NO | 16 |
| 1252408 | Trongsa | BT | 21 |
| 2667264 | Trönninge | SE | 06 |
| 6535739 | Trontano | IT | 12 |
| 2971582 | Tronville-en-Barrois | FR | B2 |
| 3165134 | Tronzano Lago Maggiore | IT | 09 |
| 3165133 | Tronzano Vercellese | IT | 12 |
+-----------+------------------------+------------+-------------+
SELECT iso_alpha2, name
FROM maxmind_countryinfo
WHERE iso_alpha2 = 'NO';
+------------+--------+
| iso_alpha2 | name |
+------------+--------+
| NO | Norway |
+------------+--------+
SELECT code, name_local
FROM maxmind_admin1_codes_ascii
WHERE code = 'NO.16';
+-------+-----------------+
| code | name_local |
+-------+-----------------+
| NO.16 | Sør-Trøndelag |
+-------+-----------------+
So basically I am trying to join these three tables with this query, I have made a special case and said ON admin1.code = 'NO.16'
SELECT
city.geonameid as city_id,
city.name as city_name,
country.name as country_name,
admin1.name_local as admin1_code
FROM maxmind_cities1000 as city
INNER JOIN maxmind_countryinfo as country
ON city.iso_alpha2 = country.iso_alpha2
INNER JOIN maxmind_admin1_codes_ascii as admin1
ON admin1.code = 'NO.16'
WHERE city.name LIKE 'tron%' LIMIT 20;
but it gives me all the rows anyways instead of just Trondheim norway, so I am doing something wrong here. I tried switching to LEFT JOIN but get the same result set. I would like the city to show up in the result set even if there are no matching rows in maxmind_admin1_codes_ascii table, the admin code has the format iso_aplha2 '.' admin1_code
+---------+------------------------+--------------+-----------------+
| city_id | city_name | country_name | admin1_code |
+---------+------------------------+--------------+-----------------+
| 1605268 | Tron | Thailand | Sør-Trøndelag |
| 8949073 | Tronca | Italy | Sør-Trøndelag |
| 3107444 | Tronchón | Spain | Sør-Trøndelag |
| 8859151 | Tronconal | Mexico | Sør-Trøndelag |
| 2821000 | Tröndel | Germany | Sør-Trøndelag |
| 3133880 | Trondheim | Norway | Sør-Trøndelag |
| 1252408 | Trongsa | Bhutan | Sør-Trøndelag |
| 2667264 | Trönninge | Sweden | Sør-Trøndelag |
| 6535739 | Trontano | Italy | Sør-Trøndelag |
| 2971582 | Tronville-en-Barrois | France | Sør-Trøndelag |
| 3165134 | Tronzano Lago Maggiore | Italy | Sør-Trøndelag |
| 3165133 | Tronzano Vercellese | Italy | Sør-Trøndelag |
+---------+------------------------+--------------+-----------------+
This is my end result query but still don't understand why it gives me all results when I just want the special case 'NO.16'. And how should I structure my query if I want the cities to show regardless of there are no matching rows in the maxmind_admin1_codes_ascii table? This is what I have so far
SELECT
city.geonameid as city_id,
city.name as city_name,
country.name as country_name,
admin1.name_local as admin1_code
FROM maxmind_cities1000 as city
INNER JOIN maxmind_countryinfo as country
ON city.iso_alpha2 = country.iso_alpha2
INNER JOIN maxmind_admin1_codes_ascii as admin1
ON admin1.code = CONCAT(city.iso_alpha2, '.', city.admin1_code)
WHERE city.name LIKE 'tron%' LIMIT 20;
+---------+------------------------+--------------+--------------------+
| city_id | city_name | country_name | admin1_code |
+---------+------------------------+--------------+--------------------+
| 1605268 | Tron | Thailand | Uttaradit |
| 8949073 | Tronca | Italy | Calabria |
| 3107444 | Tronchón | Spain | Aragon |
| 8859151 | Tronconal | Mexico | Puebla |
| 2821000 | Tröndel | Germany | Schleswig-Holstein |
| 3133880 | Trondheim | Norway | Sør-Trøndelag |
| 1252408 | Trongsa | Bhutan | Tongsa |
| 2667264 | Trönninge | Sweden | Halland |
| 6535739 | Trontano | Italy | Piedmont |
| 2971582 | Tronville-en-Barrois | France | Lorraine |
| 3165134 | Tronzano Lago Maggiore | Italy | Lombardy |
| 3165133 | Tronzano Vercellese | Italy | Piedmont |
+---------+------------------------+--------------+--------------------+
This gives the result I want, but I don't think I am doing it right because the result was unexpected with the special case of 'NO.16'. Hope someone can help out!
Not totally sure if I understand what you are trying to do - but maybe this?
SELECT
city.geonameid as city_id,
city.name as city_name,
country.name as country_name,
admin1.name_local as admin1_code
FROM maxmind_cities1000 as city
INNER JOIN maxmind_countryinfo as country
ON city.iso_alpha2 = country.iso_alpha2
LEFT OUTER JOIN maxmind_admin1_codes_ascii as admin1
ON admin1.code = CONCAT(city.iso_alpha2, '.', city.admin1_code)
AND admin1.code = 'NO.16'
WHERE city.name LIKE 'tron%' LIMIT 20;
SELECT
city.geonameid as city_id,
city.name as city_name,
country.name as country_name,
admin1.name_local as admin1_code
FROM maxmind_cities1000 as city
INNER JOIN maxmind_countryinfo as country
ON city.iso_alpha2 = country.iso_alpha2
INNER JOIN maxmind_admin1_codes_ascii as admin1
ON admin1.code = city.admin1_code
WHERE city.name LIKE 'tron%' LIMIT 20 AND city.admin1_code = 'NO.16';
I geather prices for products in different online store which are in United States (us), United Kingdom (uk) and etc. and hold it in one mysql TABLE (com) in local currency.
For example, for United States price in US Dollar, for United Kingdom - in GB pound.
TABLE com
---------------------------------------------------------------------------------------
| AUTO_INC | COUNTER | ID | CONC | VOLUME | PRICE | SHOP | DATE_G | COUNTRY |
|----------|---------|------|-----------|--------|-------|-----------|--------|---------|
| 115124 | 76720 | 2399 | prod_name | 13 | 34.23 | store1.us | 3 | us |
| 115186 | 50952 | 2399 | prod_name | 13 | 36 | store2.us | 3 | us |
| 115187 | 45828 | 2399 | prod_name | 13 | 37.44 | store3.us | 3 | us |
| 116448 | 73419 | 2399 | prod_name | 11.6 | 48 | store4.us | 3 | us |
| 116449 | 73421 | 2399 | prod_name | 13 | 65.5 | store4.us | 3 | us |
| 133334 | 22154 | 2399 | prod_name | 13 | 36.95 | store5.us | 4 | us |
| 133386 | 31646 | 2399 | prod_name | 13 | 37.44 | store3.us | 4 | us |
| 134828 | 54667 | 2399 | prod_name | 11.6 | 48 | store4.us | 4 | us |
| 134929 | 54670 | 2399 | prod_name | 13 | 65.5 | store4.us | 4 | us |
| 133337 | 22155 | 2399 | prod_name | 13 | 26.95 | store1.uk | 4 | uk |
| 133387 | 31647 | 2399 | prod_name | 13 | 17.44 | store2.uk | 4 | uk |
| 134829 | 54668 | 2399 | prod_name | 11.6 | 30 | store3.uk | 4 | uk |
| 134830 | 54671 | 2399 | prod_name | 13 | 45.5 | store4.uk | 4 | uk |
---------------------------------------------------------------------------------------
To convert prices from local currencies to US dollar I have created TABLE my_currency
TABLE my_currency
--------------------------------------
| AUTO_INC | DOMAIN | EX_RATE | DATE_G |
|----------|--------|---------|--------|
| 235 | uk | 0.6066 | 4 |
| 236 | us | 1 | 4 |
| 237 | uk | 0.6066 | 3 |
| 238 | us | 1 | 3 |
--------------------------------------
If I want to select minimum prices for us online stores (where COUNTRY = 'us'), I use the following query:
SELECT t1.* FROM com as t1
INNER JOIN (
SELECT id, conc, volume, min(price) as usd_price, date_g
FROM com
WHERE id=2399 AND date_g=4 AND country='us'
GROUP BY conc, volume) as t2
ON t1.conc=t2.conc and t1.volume=t2.volume and t1.id=t2.id and t1.price=t2.usd_price and t1.date_g=t2.date_g
ORDER BY conc DESC, volume DESC
And I get CORRECT result:
| AUTO_INC | COUNTER | ID | CONC | VOLUME | PRICE | SHOP | DATE_G | COUNTRY |
|----------|---------|------|-----------|--------|-------|-----------|--------|---------|
| 133334 | 22154 | 2399 | prod_name | 13 | 36.95 | store5.us | 4 | us |
| 134828 | 54667 | 2399 | prod_name | 11.6 | 48 | store4.us | 4 | us |
But now my goal is to select minimum price from all stores (country in ('us', 'uk')) and take into account that database holds prices in local currencies:
1. convert prices from local currencies to us dollar
2. select minimum prices in us dollar
So I tried to use the following query:
SELECT t1.auto_inc, t1.id, t1.conc, t1.volume, (t1.price / my_currency.ex_rate) as sub_price, t1.date_g
FROM com as t1
inner join my_currency
ON t1.country=my_currency.domain AND t1.date_g=my_currency.date_g
inner join (
select com.id, com.conc, com.volume, min(com.price / my_currency.ex_rate) as usd_price, com.date_g
from com
inner join my_currency
ON com.country=my_currency.domain AND com.date_g=my_currency.date_g
WHERE com.id=2399 AND com.date_g=4 AND com.country in ('us', 'uk')
GROUP BY conc, volume) as t2
on
t1.id=t2.id and
t1.conc=t2.conc and
t1.volume=t2.volume and
(t1.price / my_currency.ex_rate)=t2.usd_price and
t1.date_g=t2.date_g
ORDER BY conc DESC, volume DESC
But I get INCORRECT result:
| AUTO_INC | ID | CONC | VOLUME | SUB_PRICE | DATE_G |
|----------|------|-----------|--------|-----------|--------|
| 134828 | 2399 | prod_name | 11.6 | 48 | 4 |
CORRECT result is:
| AUTO_INC | ID | CONC | VOLUME | SUB_PRICE | DATE_G |
|----------|------|-----------|--------|-----------|--------|
| 134828 | 2399 | prod_name | 11.6 | 48 | 4 |
|----------|------|-----------|--------|-----------|--------|
| 133387 | 2399 | prod_name | 13 | 28.750412 | 4 |
Does anybody have any ideas?
sqlfiddle.com
The problem is the join on the calculated decimal value. The following works:
SELECT t1.auto_inc, t1.id, t1.conc, t1.volume,
(t1.price / my_currency.ex_rate) as sub_price, t1.date_g
FROM com as t1 inner join
my_currency
ON t1.country = my_currency.domain AND t1.date_g = my_currency.date_g
inner join
(select com.id, com.conc, com.volume, min(com.price / my_currency.ex_rate) as usd_price, com.date_g
from com inner join
my_currency
ON com.country = my_currency.domain AND
com.date_g = my_currency.date_g
WHERE com.id=2399 AND com.date_g = 4 AND
com.country in ('us', 'uk')
GROUP BY com.id, com.conc, com.volume
) as t2
on t1.id = t2.id and
t1.conc = t2.conc and
t1.volume = t2.volume and
abs((t1.price / my_currency.ex_rate) - t2.usd_price) < 0.01 and
t1.date_g = t2.date_g
ORDER BY conc DESC, volume DESC;
However, if you change the join condition on price to:
t1.price / my_currency.ex_rate = t2.usd_price and
Then it doesn't work.
It does work if you cast both results back to decimal(10, 2):
cast(t1.price / my_currency.ex_rate as decimal(10, 2)) = cast(t2.usd_price as decimal(10, 2))
It might have something to do with this note in the documentation:
In division performed with /, the scale of the result when using two
exact-value operands is the scale of the first operand plus the value
of the div_precision_increment system variable (which is 4 by
default). For example, the result of the expression 5.05 / 0.014 has a
scale of six decimal places (360.714286)
I have a MySQL table containing financial market prices.
+------------+------+--------+--------+--------+--------+
| date | pair | open | high | low | close |
+------------+------+--------+--------+--------+--------+
| 12/9/2009 | 1 | 1.4703 | 1.4783 | 1.4668 | 1.4727 |
| 12/9/2009 | 2 | 1.6287 | 1.6378 | 1.6167 | 1.6262 |
| 12/9/2009 | 3 | 0.9038 | 0.9116 | 0.9015 | 0.9086 |
| 12/9/2009 | 4 | 88.435 | 88.71 | 87.36 | 87.865 |
| 12/9/2009 | 5 | 1.064 | 1.0664 | 1.0515 | 1.0545 |
| 12/10/2009 | 1 | 1.4725 | 1.4761 | 1.4683 | 1.4732 |
| 12/10/2009 | 2 | 1.6261 | 1.6348 | 1.6214 | 1.6279 |
| 12/10/2009 | 3 | 0.9086 | 0.9192 | 0.908 | 0.9166 |
| 12/10/2009 | 4 | 87.87 | 88.47 | 87.73 | 88.2 |
| 12/10/2009 | 5 | 1.0546 | 1.0584 | 1.0479 | 1.0517 |
| 12/11/2009 | 1 | 1.4733 | 1.4778 | 1.4586 | 1.4615 |
| 12/11/2009 | 2 | 1.6278 | 1.634 | 1.6197 | 1.6262 |
| 12/11/2009 | 3 | 0.9164 | 0.9197 | 0.909 | 0.9128 |
| 12/11/2009 | 4 | 88.2 | 89.82 | 88.195 | 89.115 |
| 12/11/2009 | 5 | 1.0517 | 1.0624 | 1.0483 | 1.0602 |
+------------+------+--------+--------+--------+--------+
I want to get something like this. This is filtered by pair (where pair = 1). Every row consists of two consecutive rows.
+--------+--------+--------+--------+--------+--------+--------+--------+
| open1 | high1 | low1 | close1 | open2 | high2 | low2 | close2 |
+--------+--------+--------+--------+--------+--------+--------+--------+
| 1.4703 | 1.4783 | 1.4668 | 1.4727 | 1.4725 | 1.4761 | 1.4683 | 1.4732 |
| 1.4725 | 1.4761 | 1.4683 | 1.4732 | 1.4733 | 1.4778 | 1.4586 | 1.4615 |
+--------+--------+--------+--------+--------+--------+--------+--------+
I tried this query from https://stackoverflow.com/a/5084722/1487781 to get two consecutive dates.
select (
select max(t1.date)
from data as t1
where t1.date < t2.date
and t1.pair = 1
) as date1,
t2.date as date2
from data as t2
It worked but I can't rewrite it to suit my need as I need values and I can't just use max() to do that. Also I need to know how to generalize the solution. For example how if I need three or four consecutive rows.
Try this query:
SELECT d1.date date1,
d2.date date2,
d1.pair,
d1.open open1,
d1.high high1,
d1.low low1,
d1.close close2,
d2.open open2,
d2.high high2,
d2.low low2,
d2.close close2
FROM table1 d1
JOIN table1 d2
ON d1.pair = d2.pair
AND d1.date = d2.date - interval 1 day
Demo: http://www.sqlfiddle.com/#!2/f490d/2
Here is a version with a subquery that determines a next date for given pair number (next date = lowest date that is greater than given date):
SELECT d1.date date1,
d2.date date2,
d1.pair,
d1.open open1,
d1.high high1,
d1.low low1,
d1.close close2,
d2.open open2,
d2.high high2,
d2.low low2,
d2.close close2
FROM table1 d1
JOIN table1 d2
ON d1.pair = d2.pair
AND d2.date = (
SELECT min(date)
FROM table1 t
WHERE t.date > d1.date
AND t.pair = d1.pair
)
demo: --> http://www.sqlfiddle.com/#!2/f490d/9