How to run two different queries based on IF condition? - mysql

I have a scenario in which a table might exist in some databases. I need my query to run when the table exists and also when it doesn't. The below query when ran, gives an error Operand should contain 1 column(s). How can I make this query work without using a stored procedure? I need to use it with PySpark SQL.
SELECT IF(
EXISTS(
SELECT * FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'dbdemo' AND TABLE_NAME = 'tier_report') > 0,
(SELECT a.*, b.tierchangedate, b.tierchangetype
FROM
(SELECT mobile, enrolledstorecode as storecode, tier as customertier, isprofileupdated, DATE(profileupdatedate) as profileupdatedate, modifiedenrolledon as enrolledon, referralcode, (CASE WHEN(countrycode IS NULL) THEN '91' ELSE countrycode END) as countrycode
FROM dbdemo.member_report) a
INNER JOIN
(SELECT mobile, DATE(tierchangedate) as tierchangedate, tierchangetype FROM dbdemo.tier_report) b
ON a.mobile=b.mobile),
(SELECT mobile, enrolledstorecode as storecode, tier as customertier, isprofileupdated, DATE(profileupdatedate) as profileupdatedate, modifiedenrolledon as enrolledon, referralcode, (CASE WHEN(countrycode IS NULL) THEN '91' ELSE countrycode END) as countrycode
FROM dbdemo.member_report));

Related

MySQL execute SELECT based on condition

How to use CASE appropriately for executing SELECT query based on user input ?
On executing following query :
SELECT
CASE WHEN user_input_variable = 'y' THEN
(SELECT * FROM table_foo WHERE bar = '6f322766-0ec0-4d24-840f-c857a82a6efe')
ELSE
(SELECT 0)
END
If the user has selected 'y' then it should return records from the table, else it should return an empty result set.
I am getting error:
Operand should contain 1 column(s)
The sub-query must return not more than 1 column. Do a UNION ALL instead.
Note that the number of columns must be the same, that's why you need to select null's in the second select.
SELECT * FROM table_foo WHERE bar = '6f322766-0ec0-4d24-840f-c857a82a6efe')
and user_input_variable = 'y'
union all
SELECT 0, null, null... where user_input_variable <> 'y'
You could use the IF condition also.
IF user_input_variable = 'y'
SELECT * FROM table_foo WHERE bar = '6f322766-0ec0-4d24-840f-c857a82a6efe')

Need help DB Query for this scenario

I am unable to derive a SQL query for the following table content.
When i tried below query i am getting above said output. Can someone help me to give the required query for it.
select Name, count(Status) from mytable where Status='Open' group by mytable union
select Name, count(Status) from mytable where Status='Cleared' group by mytable
Use case expressions in the select list to do conditional aggregation.
select Name,
count(case when Status = 'Open' then 1 end) as opencnt,
count(case when Status = 'Cleared' then 1 end) as clearedcnt
from mytable
where Status in ('Open', 'Cleared')
group by Name
COUNT() counts non-null values. The case expressions above returns null when the conditions aren't fulfilled.

multiple select on stored procedure

I'm trying to do multiple selects from one table but it only shown the last select statement.
CREATE PROCEDURE `usp_GetStockCard` (IN Matecode varchar(10))
BEGIN
(select tran_date as tran_date
from TM_matbalance
where Mate_code=Matecode);
(select Mate_code as Mate_code
from TM_matbalance
where Mate_code=Matecode);
(select tran_qtyx as Qty_in
from TM_matbalance
where tran_type='IN'
and mate_code=matecode);
(select tran_qtyx as Qty_out
from TM_matbalance
where tran_type='OUT'
and mate_code=matecode);
END
I've tried to change semicolon to comma after each select statement but it said that syntax error: missing 'semicolon'.
please help.
I look at your problem and I think I solve it.
Basically there is two problems here first one is to pivot your table where your Tran_Qtyx column become Qty_In and Qty_Out based on value in Tran_Type column (IN or OUT)... That part of problem you solve with this query
SELECT Tran_Date, Mate_Code,
SUM(CASE WHEN Tran_Type = 'IN' THEN Tran_Qtyx ELSE 0 END) Qty_In,
SUM(CASE WHEN Tran_Type = 'OUT' THEN Tran_Qtyx ELSE 0 END) Qty_Out
FROM myTable
WHERE Mate_Code = 'MAT001'
GROUP BY DATE(Tran_Date)
NOTE: In your desired result I only see 'MAT001'as Mate_Code so I stick with that in this solution and exclude MAT002 from result.
More about pivot table you can read here, there you can find a link, which is good to take a look, and where you can find a lot of stuff about mysql query's.
The second part of your problem is to get Qty_Balance column. Similar problem is solved here. It's how to calculate row value based on the value in previous row.
So your complete query could look like this:
SELECT t1.Tran_Date, t1.Mate_Code, t1.Qty_In, t1.Qty_Out,
#b := #b + t1.Qty_In - t1.Qty_Out AS Qty_Balance
FROM
(SELECT #b := 0) AS dummy
CROSS JOIN
(SELECT Tran_Date, Mate_Code,
SUM(CASE WHEN Tran_Type = 'IN' THEN Tran_Qtyx ELSE 0 END) Qty_In,
SUM(CASE WHEN Tran_Type = 'OUT' THEN Tran_Qtyx ELSE 0 END) Qty_Out
FROM myTable
WHERE Mate_Code = 'MAT001'
GROUP BY DATE(Tran_Date)) AS t1
ORDER BY t1.Tran_Date;
NOTE: probably only think you should change here is table name and it's should work.
Here is SQL Fiddle so you can see how that's work!
GL!
You will need to structure your query into one, or pass in a parameter to the stored procedure to select which output/query you want, to restructure your query you will need something like:
`CREATE PROCEDURE `usp_GetStockCard` (IN Matecode varchar(10))
BEGIN
(select tran_date as tran_date, Mate_code as Mate_code, tran_qtyx as Qty
from TM_matbalance
where Mate_code=Matecode
and (tran_type='IN' or tran_type='OUT');
END`
Or try this if you have an ID column:
SELECT coalesce(ta.id, tb.id) as tran_id, coalesce(ta.tran_date, tb.tran_date) as tran_date, coalesce(ta.Mate_code, tb.Mate_code) as Mate_code, ta.tran_type as Qty_In, tb.tran_type as Qty_Out
from (select ta.*
from TM_matbalance ta
where ta.tran_type = 'IN'
and Mate_code=Matecode
) ta full outer join
(select tb.*
from TM_matbalance tb
where tb.tran_type = 'OUT'
and Mate_code=Matecode
) tb
on ta.id = tb.id ;
just replace "id" with the name of your ID column if you don't need to return the id column then remove coalesce(ta.id, tb.id) as tran_id

Conditional insert query (Row count validation). (MYSQL)

I am trying to write a query that will count and compare the number of rows of two tables on two different databases. If they are equal then a record will be inserted into another table as 'Pass', else it will result in a 'Fail'.
I haven't been able to find any answers through google searches... Here is my query that isn't working:
select
case when
((select count(1) from db1.transaction) = (select count(1) from db2.transaction))
then
insert into db3.validation (test_result) values ('pass')
else
insert into db3.validation (test_result) values ('fail')
end;
You can do this by reversing the order. Do a single insert with a select choosing the value:
insert into db3.validation(test_result)
select (case when t1.cnt1 = t2.cnt2 then 'pass' else 'fail' end)
from (select count(1) as cnt1 from db1.transaction) t1 cross join
(select count(1) as cnt2 from db2.transaction) t2;
Note that I moved the subqueries from the case to a from clause, simply because I find them easier to read this way. You can keep them in the case if you prefer.

temporary table has a count for each other table

I'm trying to make a statistics page in my php script. in order to select the count from each table I need more than 30 Queries like this
SELECT COUNT(order_id) as `uncompleted_orders` FROM `orders` WHERE `order_status` != 0
and then I need to run another query like this:
SELECT COUNT(order_id) as `completed_orders` FROM `orders` WHERE `order_status` = 1
I've tried this approach, but it didn't work:
SELECT COUNT(order_id) as `uncompleted_orders` FROM `sd_orders` WHERE `order_status` != 4;
SELECT COUNT(order_id) as `completed_orders` FROM `sd_orders` WHERE `order_status` = 4;
Is there any way to creat a new temp table in MySQL contains the count for other tables?
You could try something like this:
SELECT
(
SELECT COUNT(order_id) FROM `sd_orders` WHERE `order_status` != 4
) as `uncompleted_orders`,
(
SELECT COUNT(order_id) FROM `sd_orders` WHERE `order_status` = 4
) as `completed_orders`
You will have a result set with one row and a field for each count.
Without more information it's impossible to generalise, but there are many constructs that can help you here.
First, your example is actually from one table, and not two. This means that you can do the following...
SELECT
COUNT(CASE WHEN order_status = 4 THEN order_id END) AS complete_orders,
COUNT(CASE WHEN order_status <> 4 THEN order_id END) AS incomplete_orders
FROM
sd_orders
This works because COUNT(<something>) doesn't include an NULLs in the results. And by not including an ELSE clause, anything that doesn't match returns NULL. Another way people accomplish the same result is SUM(CASE WHEN ? THEN 1 ELSE 0 END).
Second, where you do actually have multiple tables, you can combine the results in several different ways...
-- Where you want one value from each table...
--------------------------------------------------------------------------------
SELECT
(SELECT COUNT(*) FROM table1 WHERE fieldx = ?) AS value1,
(SELECT COUNT(*) FROM table2 WHERE fieldy = ?) AS value2
-- Where you want one row of values from each table...
--------------------------------------------------------------------------------
SELECT
table1_summary.value1 AS table1_value1,
table1_summary.value2 AS table1_value2,
table2_summary.value1 AS table2_value1,
table2_summary.value2 AS table2_value2
FROM
(
SELECT
COUNT(CASE WHEN fieldx = ? THEN id END) AS value1,
COUNT(CASE WHEN fieldx <> ? THEN id END) AS value2
FROM
table1
)
AS table1_summary
CROSS JOIN
(
SELECT
COUNT(CASE WHEN fieldy = ? THEN id END) AS value1,
COUNT(CASE WHEN fieldy <> ? THEN id END) AS value2
FROM
table2
)
AS table2_summary
-- Where you want many rows, but of the same fields, from each table...
--------------------------------------------------------------------------------
SELECT
*
FROM
(
SELECT
'Table1' AS source_table,
fielda AS some_grouping,
COUNT(CASE WHEN fieldx = ? THEN id END) AS value1,
COUNT(CASE WHEN fieldx <> ? THEN id END) AS value2
FROM
table1
GROUP BY
fielda
UNION ALL
SELECT
'Table2' AS source_table,
fieldb AS some_grouping,
COUNT(CASE WHEN fieldy = ? THEN id END) AS value1,
COUNT(CASE WHEN fieldy <> ? THEN id END) AS value2
FROM
table2
GROUP BY
fieldb
)
AS summary
ORDER BY
source_table,
some_grouping,
value1,
value2
As you can see, there are a lot of ways to do this. How you approach it totally depends on your data and your needs.