SQL query with a syntax error with DATE_ADD() function (edited) - mysql

I'm writing some SQL queries, and an error occurred:
psycopg2.errors.SyntaxError: syntax error at or near "1"
LINE 10: ... AND A2.block_time < DATE_ADD(A1.block_time, INTERVAL 1 DAY)
My query where the error occurred is:
SELECT address_id
FROM address_history A1
WHERE EXISTS (
SELECT *
FROM address_history A2
WHERE A1.address_id = A2.address_id
AND A1.inflow = A2.outflow
AND A2.block_time > A1.block_time
AND A2.block_time < DATE_ADD(A1.block_time, INTERVAL 1 DAY)
AND A1.address_id IN ( ... ) # some candidates
)
and data in the block_time column are of the form:
2020-01-03 14:10:00
so I don't think I need to cast data with CAST() or DATE(). What's wrong with this SQL query?
Part of my Python code
mySQL_user = '''
SELECT address_id
FROM address_history A1
WHERE EXISTS (
SELECT *
FROM address_history A2
WHERE A1.address_id = A2.address_id
AND A1.inflow = A2.outflow
AND A2.block_time > A1.block_time
AND A2.block_time < DATE_ADD(A1.block_time, INTERVAL 1 DAY)
AND A1.address_id IN (
'''
Above code is the skeleton of my query, and I appended some candidates using:
mySQL_user += f"'{address}'"
where address is a string variable. I also separated candidates using ", "(comma), and I added two ")" at the end using:
mySQL_user += "))"

Related

How To Get My Teradata Query to Prompt For Dates Between ?YYYYMMDD AND ?YYYYMMDD and

HERE IS THE QUERY:
SELECT
FACDTE.QTR
,FACDTE.WK
,FACDTE."DATE"
,FACDTE.DIV
,FACDTE.DST
,FACDTE.FAC
,FACDTE.DAYS
,COALESCE(OOS.SCN,0) SCN
,RANK() OVER(
PARTITION BY FACDTE.QTR,FACDTE.WK,FACDTE."DATE"
ORDER BY COALESCE (CAST(OOS."OOS COUNT" AS INTEGER),'ns')) AS DIVRANK
,CAST(OOS."OOS COUNT" AS INTEGER) "OOS COUNT"
FROM
(
SELECT
FAC.PARENT_OP_AREA_CD DIV
,FAC.DISTRICT_FINANCE_CD DST
,FAC.STORE_ID FAC
,DTE.QUARTER_ID QTR
,DTE.WEEK_ID WK
,DTE.D_DATE "DATE"
,COUNT(DISTINCT(DTE.D_DATE)) DAYS
FROM LU_STORE_FINANCE FAC
JOIN (
SELECT
DTE_L1.D_DATE
,DTE_L1.WEEK_ID
,DTE_L1.QUARTER_ID
FROM LU_DAY_MERGE DTE_L1
JOIN (SELECT D_DATE FROM LU_DAY_MERGE
WHERE WEEK_ID=(SELECT DISTINCT(WEEK_ID) FROM LU_DAY_MERGE WHERE D_DATE =CURRENT_DATE -2)) DTE_L0 ON DTE_L0.D_DATE =DTE_L1.D_DATE AND DTE_L1.D_DATE < CURRENT_DATE
) DTE
ON DTE.D_DATE BETWEEN FAC.OPENED_DT AND FAC.CLOSED_DT AND
THE CODE IS BELOW I NEED TO PROMPT FOR DATES BETWEEN YYYYMMDD YYYYMMDD INSTEAD of Using the current_DATE... Can I just put in ?YYYYMMDD AND YYYYMMDD in that please?
FAC.PARENT_OP_AREA_CD = '17' AND NOT FAC.STORE_ID IN (4904,3332, 1478,0412,2631,1223) GROUP BY 1,2,3,4,5,6) FACDTE
LEFT JOIN
(SELECT
OOS_L1.STORE_ID FAC
,DTE_L2.WEEK_ID WK
,DTE_L2.D_DATE "DATE"
,AVERAGE(TOT_CT.TOT_OOS) AS "OOS COUNT"
,COUNT(DISTINCT(OOS_L1.SCAN_DT)) SCN
,SUM(CASE WHEN OOS_L1.PRODUCT_SOURCE_CD = 'W' THEN CASE WHEN ITM.DEPARTMENT_ID = 314 THEN OOS_L1.OOS_STR_SCAN_CNT ELSE 0 END ELSE 0 END) AS "DAIRY"
FROM
OOS_STORE_ITEM_DAY OOS_L1
JOIN (SELECT STORE_ID,SCAN_DT ,COUNT(UPC_ID) AS TOT_OOS FROM OOS_ITEM_DETAIL WHERE SCAN_TYP_CD = 'O' GROUP BY 1,2)TOT_CT
ON TOT_CT.STORE_ID = OOS_L1.STORE_ID AND TOT_CT.SCAN_DT=OOS_L1.SCAN_DT AND TOT_CT.TOT_OOS>49
JOIN LU_DAY_MERGE DTE_L2 ON OOS_L1.SCAN_DT=DTE_L2.D_DATE
JOIN LU_UPC ITM ON OOS_L1.UPC_ID = ITM.UPC_ID AND ITM.CORPORATION_ID = 1
GROUP BY 1,2,3) OOS
ON OOS.WK = FACDTE.WK AND OOS.FAC=FACDTE.FAC AND OOS."DATE" = FACDTE."DATE"
ORDER BY 1,2,3,4,5,6
Not saure, what the question is. But if you're talking about the feature in Teradata SQL Assistant to place parameters (with the ?-Syntax):
You can define parameters in SQL Assistant with Keyword ?. Just place ? with the parameter name (no spaces) anywhere in your Editor. SQL Assistant will ask for each parameter and search&replace it before the query is send to the database. The parameters can occur multiple times in the editor, you just have to enter the value once and it will be replaced each occurrence.
SELECT *
FROM myWebOrders
where orderDate >= CURRENT_DATE - ?OrderHistory_Days
UNION ALL
SELECT *
FROM myRetailOrders
where orderDate >= CURRENT_DATE - ?OrderHistory_Days
or
SELECT TOP 50 *
FROM ?myTable

MySql update not recognizing temporary table

I have the following query script that is resulting in an error:
SET #row_number = 0;
Drop Table If Exists testtable2;
Create Temporary Table testtable2
SELECT
*
FROM
(SELECT
row_names, (#row_number:=#row_number + 1) AS num, date_add(date_time, INTERVAL 1 MINUTE) AS date_time, meter, kw
FROM
testtable
WHERE
DAY(date_time) = 1
AND HOUR(date_time) = 2) AS testtable2
WHERE
MOD(testtable2.num, 2) = 0;
UPDATE testtable
SET
testtable.date_time = testtable2.date_time
WHERE
testtable.row_names = testtable2.row_names;
The error says Error Code: 1054. Unknown column 'testtable2.row_names' in 'where clause'
I created a temporary table that contains the column date_time but my update query fails to recognize that the column exists. I can run something like SELECT * FROM testtable2; and it returns showing that the column is indeed generated with the correct title. Why can my update not recognize this column?
This is your update statement:
UPDATE testtable
SET testtable.date_time = testtable2.date_time
WHERE testtable.row_names = testtable2.row_names;
What is testtable? You have not defined that. You created testtable2. If you do have testtable, then perhaps you want a join:
UPDATE testtable tt JOIN
testtable2 tt2
ON tt.row_names = tt2.row_names
SET tt.date_time = tt2.date_time;
You actually meant to use CREATE TABLE ... AS construct but in your case it's wrongly formed. It should be like below.
Create Temporary Table testtable2 AS
SELECT
*
FROM
(SELECT
row_names, (#row_number:=#row_number + 1) AS num,
date_add(date_time, INTERVAL 1 MINUTE) AS date_time,
meter,
kw
FROM
testtable
WHERE
DAY(date_time) = 1
AND HOUR(date_time) = 2) AS XXX <-- Here
WHERE
MOD(testtable2.num, 2) = 0;
Issue in your case is, your Temporary table and inline view alias are same. name them differently. See edited query.
You can directly JOIN with the inner query and can perform UPDATE like
UPDATE testtable
JOIN (
SELECT
*
FROM
(SELECT
row_names, (#row_number:=#row_number + 1) AS num, date_add(date_time, INTERVAL 1 MINUTE) AS date_time, meter, kw
FROM
testtable
WHERE
DAY(date_time) = 1
AND HOUR(date_time) = 2) AS testtable2
WHERE
MOD(testtable2.num, 2) = 0 ) xx ON testtable.row_names = xx.row_names
SET
testtable.date_time = xx.date_time;

getting error from mysqli_fetch_array

My query line is:
SELECT TR.*,
PL.*, DE.*,
( DE.power + DE.stamina + DE.violence + DE.speed + DE.shooting + DE.scoring + DE.pass + DE.ball_control + DE.talent ) AS TPOWER,
strftime('%Y-%d-%m', DE.age, 'unixepoch') AS age
FROM `transfers` TR JOIN `players` PL ON TR.player_id=PL.id
JOIN `playerdetails` DE ON TR.player_id=DE.player_id
WHERE PL.position = 'MD' AND ( age >= '20' AND age <= '24' )
AND PL.firstname = 'a' AND PL.lastname = 'b' AND TPOWER >= '1'
AND TPOWER <= '5' AND TR.price >= '20' AND TR.price <= '50'
ORDER BY age DESC
What's wrong with this query?
An error occurred:
Warning: mysqli_fetch_array() expects parameter 1 to be mysqli_result, boolean given in E:\EasyPHP-Devserver-16.1\eds-www\classes\DB.php on line 15
MySQL doesn't have a function called strftime(). You might want date_format() instead:
SELECT . . .
date_format(de.age, '%Y-%d-%m') AS age
However, that seems like a strange way to express the age (which is usually an integer, number, or interval).
Your query could have other errors as well. You should check the error messages that are returned.

Mysql if statement to select multiple rows

I need to retrieve a set of data if a condition is true, and a set of other ata if the condition is false.
I searched in mysql manual and I tested the select case when statement, but as my subqueries return multiple rows, I'm not able to use it.
Is it a simple way to write a query with if statement? (without using stored procedure)
Here is my condition:
select case when ( right(from_unixtime(300 * floor(unix_timestamp(now())/300)) - INTERVAL 10 MINUTE, 8) = '23:50:00' ) then ( select SERVER_KEY from OVERSERVER ) else ( select SERVER_KEY from SERVER ) end;
Thanks
try something like this:
select SERVER_KEY from OVERSERVER
where right(from_unixtime(300 * floor(unix_timestamp(now())/300)) - INTERVAL 10 MINUTE, 8) = '23:50:00'
union all
select SERVER_KEY from SERVER
where right(from_unixtime(300 * floor(unix_timestamp(now())/300)) - INTERVAL 10 MINUTE, 8) != '23:50:00'
I am not sure but just give a try this-
select SERVER_KEY from (case when ( right(from_unixtime(300 * floor(unix_timestamp(now())/300)) - INTERVAL 10 MINUTE, 8) = '23:50:00' ) then "OVERSERVER" else "SERVER"
OR
select SERVER_KEY from (case when ( right(from_unixtime(300 * floor(unix_timestamp(now())/300)) - INTERVAL 10 MINUTE, 8) = '23:50:00' ) then OVERSERVER else SERVER
Note: above query is not tested.

MySQL: Using alias in select arithmetic - Unknown field

Here's my select:
SELECT
SUM(t.amount + c.designFeeValue) as cashReceived,
ROUND(SUM(i.value) * (m.percentOurs / 100)) as adValue,
m.managementFee as managementFee,
m.productionCost as productionCost,
5 as emailAddress,
(
(
SELECT value
FROM commission_transactions
WHERE isDebit IS
TRUE
) -
(
SELECT value
FROM commission_transactions
WHERE isDebit IS
FALSE
)
) as miscExpenses,
(managementFee + productionCost + emailAddress + miscExpenses) as totalExpenses
This is bombing because of the following line, where I add up some aliases.
(managementFee + productionCost + emailAddress + miscExpenses) as totalExpenses
The aliases are unknown fields.
Is there a way I can keep the aliases for this arithmetic or do I need to re-do all the math that generates each alias for the calculation of totalExpenses? That seems like a very ugly way to do it.
UPDATE:
Per your suggestions, I am now using a derived table.
SELECT
cashReceived,
adValue,
managementFee,
productionCost,
emailAddress,
miscExpenses,
adValue + managementFee + productionCost + emailAddress + miscExpenses as totalExpenses
FROM (
SELECT
SUM(t.amount + c.designFeeValue) as cashReceived,
ROUND(SUM(i.value) * (m.percentOurs / 100)) as adValue,
m.managementFee as managementFee,
m.productionCost as productionCost,
5 as emailAddress,
(
(
SELECT value
FROM commission_transactions
WHERE isDebit IS TRUE
) -
(
SELECT value
FROM commission_transactions
WHERE isDebit IS FALSE
)
) as miscExpenses
FROM magazines m
JOIN insertions i ON i.magazineId = m.id
JOIN transactions t ON t.insertionId = i.id
JOIN contracts c ON i.contractId = c.id
JOIN commission_transactions ct ON m.id = ct.magazineId
WHERE m.id = 17
AND t.isChargedBack IS FALSE
AND t.`timestamp` >= '2013-08-01 00:00:00'
AND t.`timestamp` < '2013-09-01 00:00:00'
AND ct.createdDate >= '2013-08-01 00:00:00'
AND ct.createdDate < '2013-09-01 00:00:00'
) sub;
Aliases aren't available for re-use within the field list, e.g:
mysql> select 5 as five, five + 1 as six;
ERROR 1054 (42S22): Unknown column 'five' in 'field list'
You'll have to wrap the select with another one, then do your alias math in that wrapper, e.g.
select *, managementFee + productionCost + emailAddress + miscExpenses) as totalExpenses
FROM (
... your above query here ...
)