MySQL query from subquery not working - mysql

I am trying to return a number based on the count of results from a table and to avoid having to count the results twice in the IF statement I am using a subquery. However I get a syntax error when trying to run the query, the subquery I have tested by itself runs fine.
Any ideas what is wrong with the query? The syntax looks correct to me
SELECT IF(daily_count>8000,0,IF(daily_count>6000,1,2))
FROM (
SELECT count(*) as daily_count
FROM orders201003
WHERE DATE_FORMAT(date_sub(curdate(), INTERVAL 1 DAY),"%d-%m-%y") =
DATE_FORMAT(reqDate,"%d-%m-%y")
) q
Error message I get is:
You have an error in your SQL syntax.
Check the manual that corresponds to
your MySQL server version for the
right syntax to use near 'SELECT
count(*) as daily_count
FROM orders201003

SELECT CASE WHEN daily_count > 8000 THEN 0 WHEN daily_count > 6000 THEN 1 ELSE 2 END
FROM (
SELECT count(*) as daily_count
FROM orders201003
WHERE DATE_FORMAT(date_sub(curdate(), INTERVAL 1 DAY),"%d-%m-%y") =
DATE_FORMAT(reqDate,"%d-%m-%y")
) AS q
Also note that the nested queries are only supported starting from MySQL 4.1.

Related

Delete duplicates for multiple columns in JOIN on same table

I am trying to make a delete from joined same table like this:
DELETE FROM `sp10_seo_url` AS sp1 JOIN
(
SELECT seo_url_pk, COUNT(*) AS maxc
FROM `sp10_seo_url`
GROUP BY seo_url_entity_type, seo_url_entity_id, seo_url_language_fk
HAVING maxc > 1
) AS sp2
ON sp1.seo_url_pk = sp2.seo_url_pk
However I am getting a mysql error
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'AS sp1 JOIN ( SELECT seo_url_pk, COUNT(*) AS maxc FROM `sp10_s' at line 1
And I am not sure at all where the error is. The inner query runs just fine and returns the expected set of results. The "ON" keys are properly named (same since we are talking about the same table).
I guess the idea of the query is pretty clear (clean the table of different rows have the same set of values for the three "group by" columns. Is there another way to do this?
Thanks!
you can "cheat" mysql with a double indirection (as explained here Deleting a row based on the max value):
delete from `sp10_seo_url`
where seo_url_pk in (
select seo_url_pk from (
SELECT seo_url_pk
FROM `sp10_seo_url` sp1,
(
SELECT seo_url_entity_type, seo_url_entity_id, seo_url_language_fk
FROM `sp10_seo_url`
GROUP BY seo_url_entity_type, seo_url_entity_id, seo_url_language_fk
HAVING count(*) > 1
) sp2
where sp1.seo_url_entity_type = sp2.seo_url_entity_type
and sp1.seo_url_entity_id = sp2.seo_url_entity_id
and sp1.seo_url_language_fk = sp2.seo_url_language_fk
) t
);
http://sqlfiddle.com/#!2/899ff5/1

How to use SELECT DISTINCT ON with MySQL and Rails

I have quite a complex query to essentially select the cheapest delivery service price per delivery service.
In order to get unique records per delivery service, I utilise the DISTINCT function in SQL. This query provides correct results:
DeliveryServicePrice.active.select('DISTINCT ON (delivery_service_id) *').order('delivery_service_id, price ASC')
(only a part of the query)
However, this query only seems to work with PostgreSQL (which I think is strange considering PostgreSQL is a lot more strict with SQL standards); it does not work with MySQL and SQLite. I receive the following error:
Mysql2::Error: You have an error in your SQL syntax; check the manual
that corresponds to your MySQL server version for the right syntax to
use near 'ON (delivery_service_id) * FROM `delivery_service_prices`
WHERE `delivery_servi' at line 1: SELECT DISTINCT ON
(delivery_service_id) * FROM `delivery_service_prices` WHERE
`delivery_service_prices`.`active` = 1 AND (2808.0 >= min_weight AND
2808.0 <= max_weight AND 104.0 >= min_length AND 104.0 <= max_length AND 104.0 >= min_thickness AND 104.0 <= max_thickness) ORDER BY delivery_service_id, price ASC
The application I'm building is open source, so it's required to support all 3 database types.
How do I create DISTINCT ON queries for MySQL and SQLite in the Rails framework syntax?
I'm using Rails 4.1.
Resources
My previous problem for reference:
How to select unique records based on foreign key column in Rails?
File and line number for where the query is being used.
Finished answer
DeliveryServicePrice.select('delivery_service_prices.id').active.joins('LEFT OUTER JOIN delivery_service_prices t2 ON (delivery_service_prices.delivery_service_id = t2.delivery_service_id AND delivery_service_prices.price > t2.price)').where('t2.delivery_service_id IS NULL')
DISTINCT ON is a Postgres specific extension to the standard SQL DISTINCT. Neither of them is a "function", both are SQL key words - even though the parentheses required after DISTINCT ON make it look like a function.
There are a couple of techniques to rewrite this with standard-SQL, all of them more verbose, though. Since MySQL does not support window-functions row_number() is out.
Details and more possible query techniques:
Select first row in each GROUP BY group?
Fetch the row which has the Max value for a column
Rewritten with NOT EXISTS:
SELECT *
FROM delivery_service_prices d1
WHERE active = 1
AND 2808.0 BETWEEN min_weight AND max_weight
AND 104.0 BETWEEN min_length AND max_length
AND 104.0 BETWEEN min_thickness AND max_thickness
AND NOT EXISTS (
SELECT 1
FROM delivery_service_prices d2
WHERE active = 1
AND 2808.0 BETWEEN min_weight AND max_weight
AND 104.0 BETWEEN min_length AND max_length
AND 104.0 BETWEEN min_thickness AND max_thickness
AND d2.delivery_service_id = d1.delivery_service_id
AND d2.price < d1.price
AND d2.<some_unique_id> < d1.<some_unique_id> -- tiebreaker!
)
ORDER BY delivery_service_id
If there can be multiple rows with the same price for the same delivery_service_id, you need to add some unique tie-breaker to avoid multiple results per delivery_service_id. At least if you want a perfectly equivalent query. My example would select the row with the smallest <some_unique_id> from each set of dupes.
Unlike with DISTINCT ON, ORDER BY is optional here.
DeliveryServicePrice.active.select(:delivery_service_id).distinct.order('delivery_service_id, price ASC')

Adding a date format to FROM_UNIXTIME breaks query

Trying to run this query:
SELECT FROM_UNIXTIME(offers_consumers_history.date,
`'%d-%m-%Y')` AS date,
COUNT(*) AS COUNT
FROM (`offers_history`)
JOIN `offers_consumers_history` ON `offers_consumers_history`.`offer_history_id`=`offers_history`.`id`
WHERE `offers_history`.`merchant_id` = 1
AND `offers_history`.`offer_type_id` = 1
GROUP BY DATE(FROM_UNIXTIME(offers_consumers_history.date))
ORDER BY `offers_consumers_history`.`date`
If I run it without a date format on my first FROM_UNIXTIME (the %d-%m-%Y part), everything runs fine, but I'm obviously not getting the right date format displayed, the returned error is:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FROM (`offers_history`) JOIN `offers_consumers_history` ON `offers_consumers_his' at line 2
Without a date format I'm getting results such as:
{"date":"2010-08-18 18:40:00","count":"2"}
What I want is:
{"date":"18-08-2010","count":"2"}
count is a reserved word, you can't use it as alias, use different name
'%d-%m-%Y') AS dt,
COUNT(*) AS cnt
OR with backticks
(offers_consumers_history.date,'%d-%m-%Y') AS `date`,
COUNT(*) AS `COUNT`
Remove the () from the table name and change the alias name of count:
SELECT FROM_UNIXTIME(offers_consumers_history.date,
'%d-%m-%Y') AS `date`,
COUNT(*) AS cnt
FROM `offers_history`
JOIN `offers_consumers_history` ON `offers_consumers_history`.`offer_history_id`=`offers_history`.`id`
WHERE `offers_history`.`merchant_id` = 1
AND `offers_history`.`offer_type_id` = 1
GROUP BY DATE(FROM_UNIXTIME(offers_consumers_history.date))
ORDER BY `offers_consumers_history`.`date`

error in my mysql query

i have a query that fetches data's from differant tables
SELECT p.USER_NAME,count(*) as total, pi.UpdatedDate FROM purchase p JOIN purchasedissues pi on pi.PurchaseId=p.PURCHASE_ID WHERE pi.UpdatedDate>DATE_SUB(NOW(), INTERVAL 1 HOUR) AND p.PURCHASE_DATE=CURDATE() AND p.USER_NAME NOT IN (SELECT username from tbl_test_user) GROUP BY p.USER_NAME having count(*)>2
but i got an error that
#1064 - You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use
near 'SELECT p.USER_NAME,count(*) as total, pi.UpdatedDate FROM
purchase p JOIN pur' at line 1
i can't figure it. please any one help me
thanks in advance
Your query is ok. The error is indicating that it is near your SELECT p.USER_NAME,.... This usually happens when you are executing multiple query without terminating it. Ex,
SELECT * FROM tableName
SELECT p.USER_NAME,count(*) as total, pi.UpdatedDate FROM purchase....
so to correct it, just add a delimiter (usually if not change, it's semi-colon) to end your first query
SELECT * FROM tableName; -- <== this one
SELECT p.USER_NAME,count(*) as total, pi.UpdatedDate FROM purchase....
Try this query! not sure if it works as I don't have the environment set in my machine but it may give you an essence to test it :)
SELECT p.USER_NAME,count(*) as total FROM purchase p JOIN purchasedissues pi on pi.PurchaseId=p.PURCHASE_ID WHERE pi.UpdatedDate>DATE_SUB(NOW(), INTERVAL 1 HOUR) AND p.PURCHASE_DATE=CURDATE() AND p.USER_NAME NOT IN (SELECT username from tbl_test_user) GROUP BY p.USER_NAME having total > 2

MySQL to Oracle Syntax Error (Limit / Offset / Update)

I have a MySQL query that works on my current MySQL database. I've been forced to move over to oracle, so I'm trying to port all my stored procedures / programs to use the Oracle SQL Syntax. I'm having a lot of trouble on one particular query. Here is the MySQL query. It updates a table using a subquery.
update table1 alf
set nextcontractid =
(
select
contractid from table1copy alf2
where
alf2.assetid = alf.AssetID
and
alf2.lasttradedate > alf.LastTradeDate
order by lasttradedate asc limit 1
)
where complete = 0
In oracle, I can't use the the limit command, so I've looked for the workaround. Here is my oracle query. (which doesn't work.)
update table1 alf
set nextcontractid =
(select contractid from
(
SELECT contractid, rownum as row_number
FROM table1copy alf2
WHERE alf2.assetid = alf.assetid
AND alf2.lasttradedate > alf.lasttradedate
ORDER BY lasttradedate ASC
)
where row_number = 1)
where alf.complete = 0
I get the following error:
Error at Command Line:8 Column:29
Error report:
SQL Error: ORA-00904: "ALF"."LASTTRADEDATE": invalid identifier
00904. 00000 - "%s: invalid identifier"
line 8 is:
AND alf2.lasttradedate > alf.lasttradedate
Removing the update statement and putting in some dummy values into the subquery yields the correct results for the subquery:
(select contractid from
(
SELECT contractid, rownum as row_number
FROM asset_list_futures_copy alf2
WHERE alf2.assetid = 'GOLD'
AND alf2.lasttradedate > '20110101'
ORDER BY lasttradedate ASC
)
where row_number = 1)
Looking at the error, it looks like the second reference to alf isn't working. Any idea how I can change my query so that it works in oracle?
Seems the parser does not like that, despite the fact it is sintacticaly correct. Probably the two imbricated and ordered clause is blinding him somehow. I reproduced that.
You can use an analytical function:
update table1 alf
set nextcontractid =
(SELECT min(contractid) keep (dense_rank first order by lasttradedate asc)
FROM table1copy alf2
WHERE alf2.assetid = alf.assetid
AND alf2.lasttradedate > alf.lasttradedate
)
where alf.complete = 0
You can use WHERE rownum = 1, or rownum BETWEEN x AND y in cases that you want more results.